CPP04 1.0
読み取り中…
検索中…
一致する文字列を見つけられません
Tests.cpp
[詳解]
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* Tests.cpp :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: kamitsui <kamitsui@student.42tokyo.jp> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2025/06/03 20:25:55 by kamitsui #+# #+# */
9/* Updated: 2025/06/03 20:26:42 by kamitsui ### ########.fr */
10/* */
11/* ************************************************************************** */
12
17#include "Tests.hpp"
18#include "Animal.hpp"
19#include "Cat.hpp"
20#include "Dog.hpp"
21#include "ScopedPointer.hpp" // 自作したスマートポインタ
22#include "WrongAnimal.hpp"
23#include "WrongCat.hpp"
24#include <cstdlib> // EXIT_FAILURE のために必要
25#include <iostream>
26
28 std::cout << "\n--- Wrong Polymorphism ---" << std::endl;
29
30 // ScopedPointer を使用してリソースを自動管理
31 // new が失敗した場合でも、ScopedPointer のデストラクタが呼ばれる
32 // 割り当て失敗時のエラーハンドリングも Try-Catch で捕捉できる
35
36 try {
37 wrongMeta.reset(new WrongAnimal()); // new に失敗したら std::bad_alloc をスロー
38 wrongJ.reset(new WrongCat()); // new に失敗したら std::bad_alloc をスロー
39
40 // get() を使って生ポインタを取得し、null チェックする (防御的プログラミング)
41 if (wrongJ.get()) {
42 std::cout << wrongJ->getType() << " " << std::endl;
43 }
44 if (wrongJ.get()) {
45 wrongJ->makeSound(); // "Wrong generic animal sound"
46 }
47 if (wrongMeta.get()) {
48 std::cout << wrongMeta->getType() << " " << std::endl;
49 }
50 if (wrongMeta.get()) {
51 wrongMeta->makeSound(); // "Wrong generic animal sound"
52 }
53
54 // 明示的な delete は不要。ScopedPointer のデストラクタがスコープを抜けるときに呼ばれる。
55
56 } catch (const std::bad_alloc &e) {
57 // メモリ割り当て失敗の例外を捕捉
58 std::cerr << "Error: Memory allocation failed in wrongPolymorphism! " << e.what() << std::endl;
59 // 例外捕捉後、ScopedPointer のデストラクタが自動で呼ばれ、
60 // 既に割り当てたメモリは解放されることが保証される。
61 // ここで return すると、関数を抜ける際にスタック上のScopedPointerもデストロイされる。
62 return EXIT_FAILURE; // 関数を異常終了させる
63 } catch (const std::exception &e) {
64 // その他の標準例外を捕捉
65 std::cerr << "An unexpected standard error occurred in wrongPolymorphism: " << e.what() << std::endl;
66 return EXIT_FAILURE;
67 } catch (...) {
68 // 捕捉しきれない例外を捕捉
69 std::cerr << "An unknown error occurred in wrongPolymorphism." << std::endl;
70 return EXIT_FAILURE;
71 }
72
73 // 関数終了時に wrongMeta と wrongJ の ScopedPointer デストラクタが呼ばれ、
74 // それらが管理していたメモリが自動的に解放される。
75
76 std::cout << "--- Wrong Polymorphism finished ---" << std::endl;
78 return 0;
79}
80
82 std::cout << "\n--- Animal Regular Tests ---" << std::endl;
83
84 // Test objects created on the stack to see constructor/destructor calls
85 Animal basicAnimal;
86 Dog basicDog;
87 Cat basicCat;
88
89 // Call getType() and makeSound() on stack objects
90 std::cout << basicAnimal.getType() << " " << std::endl;
91 std::cout << basicDog.getType() << " " << std::endl;
92 std::cout << basicCat.getType() << " " << std::endl;
93 basicAnimal.makeSound();
94 basicDog.makeSound();
95 basicCat.makeSound();
96
98}
99
101 std::cout << "\n--- Animal Array Sounds ---" << std::endl;
102
103 // Test polymorphic array
104 ScopedPointer<Animal> animalArray[4]; // ScopedPointer array
105 try {
106 animalArray[0].reset(new Dog()); // newが失敗しても、既に確保されたものはRAIIで解放
107 animalArray[1].reset(new Cat());
108 animalArray[2].reset(new Dog());
109 animalArray[3].reset(new Cat());
110
111 for (int k = 0; k < 4; ++k) {
112 // nullチェックは必要 (new が失敗した場合) : Defensive Programming 防御的プログラミング
113 if (animalArray[k].get()) {
114 std::cout << animalArray[k]->getType() << " says: ";
115 animalArray[k]->makeSound();
116 }
117 }
118 } catch (const std::bad_alloc &e) {
119 std::cerr << "Error: Memory allocation failed in array! " << e.what() << std::endl;
120 // 例外を捕捉後、配列内のScropePointerデストラクタが呼ばれ、
121 // 既に割り当てたメモリが解放されることが保証される。
122 // ここで return すると、関数を抜ける際に残りのanimalArray要素も解放される。
123 return EXIT_FAILURE;
124 }
126 return 0;
127}
128
130 std::cout << "\n--- Copy Constructor and Assignment (Regular) ---" << std::endl;
131 Dog anotherDog;
132 Dog yetAnotherDog(anotherDog); // Copy constructor
133 Cat anotherCat;
134 Cat yetAnotherCat;
135 yetAnotherCat = anotherCat; // Copy assignment operator
136
137 std::cout << anotherDog.getType() << " copied to " << yetAnotherDog.getType() << std::endl;
138 std::cout << anotherCat.getType() << " assigned to " << yetAnotherCat.getType() << std::endl;
139
141}
142
144 std::cout << "\n--- More Tests (Wrong) ---" << std::endl;
145 // Test wrong objects on the stack
146 WrongAnimal basicWrongAnimal;
147 WrongCat basicWrongCat;
148
149 std::cout << basicWrongAnimal.getType() << " " << std::endl;
150 std::cout << basicWrongCat.getType() << " " << std::endl;
151 basicWrongAnimal.makeSound();
152 basicWrongCat.makeSound();
153
155}
156
158 std::cout << "\n--- Wrong Animal Array Sounds ---" << std::endl;
159
160 // Use ScopedPointer array for RAII
161 // If 'new WrongCat()' fails partway through, the ScopedPointers
162 // already created will automatically free their resources.
163 ScopedPointer<WrongAnimal> wrongAnimalArray[2];
164
165 try {
166 wrongAnimalArray[0].reset(new WrongCat());
167 wrongAnimalArray[1].reset(new WrongCat()); // If this fails, wrongAnimalArray[0] is still cleaned up
168
169 // --- Demonstrate makeSound() behavior (NO polymorphic dispatch for WrongCat) ---
170 for (int l = 0; l < 2; ++l) {
171 // Defensive null check:
172 // Though new should throw std::bad_alloc, this ensures safety
173 // if a pointer somehow became null (e.g., new(std::nothrow) was used)
174 if (wrongAnimalArray[l].get()) {
175 std::cout << wrongAnimalArray[l]->getType() << " says: ";
176 wrongAnimalArray[l]->makeSound(); // Will output WrongAnimal sound (static binding)
177 } else {
178 std::cerr << "Array element is null, skipping makeSound() call." << std::endl;
179 }
180 }
181
182 // Explicit 'delete' calls are no longer needed.
183 // ScopedPointer's destructors handle deallocation when they go out of scope.
184
185 } catch (const std::bad_alloc &e) {
186 // Catch block handles memory allocation failures
187 std::cerr << "Error: Memory allocation failed in wrongAnimalArraySounds! " << e.what() << std::endl;
188 // The ScopedPointer destructors for successfully allocated objects
189 // will be called automatically as they go out of scope.
190 return EXIT_FAILURE; // Exit the function gracefully upon failure
191 } catch (const std::exception &e) {
192 // Catch other standard exceptions
193 std::cerr << "An unexpected standard error occurred in wrongAnimalArraySounds: " << e.what() << std::endl;
194 return EXIT_FAILURE;
195 } catch (...) {
196 // Catch any other unknown exceptions
197 std::cerr << "An unknown error occurred in wrongAnimalArraySounds." << std::endl;
198 return EXIT_FAILURE;
199 }
200
201 // When the function ends, 'wrongAnimalArray' (which contains ScopedPointer objects)
202 // goes out of scope. Each ScopedPointer's destructor is called,
203 // ensuring the dynamically allocated 'WrongAnimal' objects are deleted.
204 std::cout << "--- Wrong Animal Array Sounds finished ---" << std::endl;
205
206 // Test wrong polymorphic array
207 // WrongAnimal *wrongAnimalArray[2];
208 // wrongAnimalArray[0] = new WrongCat();
209 // wrongAnimalArray[1] = new WrongCat();
210
211 // std::cout << "--- Wrong Animal Array Sounds ---" << std::endl;
212 // for (int l = 0; l < 2; ++l) {
213 // std::cout << wrongAnimalArray[l]->getType() << " says: ";
214 // wrongAnimalArray[l]->makeSound(); // Will output WrongAnimal sound (static binding)
215 // }
216
218 // for (int l = 0; l < 2; ++l) {
219 // delete wrongAnimalArray[l];
220 // }
221
222 // std::cout << std::endl;
223 return 0;
224}
225
227 std::cout << "\n--- Copy Constructor and Assignment (Wrong) ---" << std::endl;
228 WrongCat anotherWrongCat;
229 // Copy constructor
230 WrongCat yetAnotherWrongCat(anotherWrongCat);
231 WrongAnimal yetAnotherWrongAnimal;
232 // Note: Assignment of WrongCat to WrongAnimal (slicing might occur if not careful with ownership)
233 yetAnotherWrongAnimal = anotherWrongCat;
234
235 std::cout << anotherWrongCat.getType() << " copied to " << yetAnotherWrongCat.getType() << std::endl;
236 std::cout << yetAnotherWrongCat.getType() << " assigned to " << yetAnotherWrongAnimal.getType() << std::endl;
237 // Will output WrongAnimal sound due to static binding on WrongAnimal object
238 yetAnotherWrongAnimal.makeSound();
239
241}
void wrongAnimalCopyConstAndAssignment(void)
Definition Tests.cpp:226
void wrongAnimalRegularTests(void)
Definition Tests.cpp:143
int wrongPolymorphism(void)
Definition Tests.cpp:27
int wrongAnimalArraySounds(void)
Definition Tests.cpp:157
void animalRegularTests(void)
Definition Tests.cpp:81
int animalArraySounds(void)
Definition Tests.cpp:100
void animalCopyConstAndAssignment(void)
Definition Tests.cpp:129
Define More Tests Function.
The Animal class represents a generic animal.
Definition Animal.hpp:37
const std::string & getType() const
Gets the type of the animal.
Definition Animal.cpp:72
virtual void makeSound() const
Makes a generic animal sound. This implementation is for the base Animal class. Derived classes are e...
Definition Animal.cpp:66
The Cat class represents a feline animal.
Definition Cat.hpp:33
virtual void makeSound() const
Makes the characteristic sound of a cat ("Meow!"). This function overrides the virtual makeSound() fr...
Definition Cat.cpp:65
The Dog class represents a canine animal.
Definition Dog.hpp:33
virtual void makeSound() const
Makes the characteristic sound of a dog ("Woof!"). This function overrides the virtual makeSound() fr...
Definition Dog.cpp:65
void reset(T *ptr=0)
T * get() const
The WrongAnimal class represents a generic animal, used to demonstrate the LACK of polymorphism when ...
const std::string & getType() const
Gets the type of the WrongAnimal.
void makeSound() const
Makes a generic sound for a WrongAnimal. This function is intentionally NOT VIRTUAL to show the lack ...
The WrongCat class represents a feline animal in the "wrong" hierarchy.
Definition WrongCat.hpp:34
void makeSound() const
Makes the characteristic sound of a WrongCat ("Wrong meow!").
Definition WrongCat.cpp:73
T endl(T... args)
Declares the abstract Animal base class.
Declares the Cat class.
Declares the Dog class.
Declares the WrongAnimal class.
Declares the WrongCat class.
ScopedPointer Class is Custom smart pointer with RAII pattern applied.
T what(T... args)