KEMBAR78
C++ Programming - 12th Study | PDF
3
4
5
6
7
class Baz : public Foo, public Bar
{
// Something
};
8
class Dog
{
public:
virtual void bark() { cout << "Woof!" << endl; }
};
class Bird
{
public:
virtual void chirp() { cout << "Chirp!" << endl; }
};
class DogBird : public Dog, public Bird
{ };
9
DogBird confusedAnimal;
confusedAnimal.bark();
confusedAnimal.chirp();
10
class Dog {
public:
virtual void bark() { cout << "Woof!" << endl; }
virtual void eat() { cout << "The dog has eaten." << endl; }
};
class Bird {
public:
virtual void chirp() { cout << "Chirp!" << endl; }
virtual void eat() { cout << "The bird has eaten." << endl; }
};
11
DogBird confusedAnimal;
confusedAnimal.eat();
error C2385: ambiguous access of 'eat'
note: could be the 'eat' in base 'Dog'
note: or could be the 'eat' in base 'Bird'
static_cast<Dog>(confusedAnimal).eat(); // 슬라이싱, Dog::eat() 호출
confusedAnimal.Dog::eat(); // 명시적으로 Dog::eat() 호출
void DogBird::eat()
{
Dog::eat(); // 명시적으로 Dog의 eat() 호출
}
12
class Dog
{
public:
virtual void eat()
{
cout << "The bird has eaten." << endl;
}
};
class Bird : public Dog {};
class DogBird : public Bird, public Dog {};
DogBird confusedAnimal;
confusedAnimal.eat();
error C2385: ambiguous access of 'eat'
note: could be the 'eat' in base 'Dog'
note: or could be the 'eat' in base 'Dog'
13
class Animal
{
public:
virtual void sleep() { cout << "Zzz..." << endl; }
};
class Dog : public Animal { … };
class Bird : public Animal { … };
confusedAnimal.sleep();
error C2385: ambiguous access of 'sleep'
note: could be the 'sleep' in base 'Animal'
note: or could be the 'sleep' in base 'Animal
14
class Animal {
public:
virtual void sleep() = 0;
};
class Dog : public Animal {
public:
virtual void sleep() { … }
};
class Bird : public Animal {
public:
virtual void sleep() { … }
};
class DogBird : public Dog, public Bird {
public:
virtual void sleep() { Dog::sleep(); }
};
15
class Animal
{
public:
virtual void sleep() { cout << "Zzz..." << endl; }
};
class Dog : public virtual Animal { … };
class Bird : public virtual Animal { … };
confusedAnimal.sleep(); // Animal이 virtual이기 때문에 모호하지 않음
17
class Super
{
public:
void go() { cout << "Super::go()" << endl; }
};
class Sub : public Super
{
public:
void go() { cout << "Sub::go()" << endl; }
};
Sub mySub;
mySub.go();
Sub::go()
Sub mySub;
Super& ref;
ref = mySub;
ref.go();
Super::go()
18
19
class Super
{
public:
virtual void func1() { }
virtual void func2() { }
};
class Sub : public Super
{
public:
virtual void func2() { }
};
Super mySuper;
Sub mySub;
vtable
mySuper
vtable
mySub
func1
func2
func1
func2
Super::func1()
구현부
Super::func2()
구현부
Sub::func2()
구현부
20
21
class Super {
public:
Super() { }
~Super() { }
};
class Sub : public Super {
private:
char* mString;
public:
Sub() { mString = new char[30]; }
~Sub() { delete[] mString; }
};
Super* ptr = new Sub(); // mString은 이 시점에 할당됨
delete ptr; // ~Super가 호출되었지만
// virtual이 아니기 때문에
// ~Sub는 호출되지 않음
23
24
참고 : http://prostars.net/55
#include <iostream>
using namespace std;
class Base
{
public:
virtual void print() { cout << "Base" << endl; }
};
class Derived : public Base
{
public:
virtual void print() { cout << "Derived" << endl; }
};
25
참고 : http://prostars.net/55
Base* base1 = new Base;
Base* base2 = new Derived;
Derived* derived1 = new Derived;
Derived* derived2 = nullptr;
// 컴파일 오류 : 타입 변환을 할 수 없다.
// derived2 = base1;
// 컴파일 성공 : 런타임에 타입 변환에 실패하며
// nullptr을 반환한다.
derived2 = dynamic_cast<Derived*>(base1);
if (derived2 == nullptr)
cout << "Runtime Error" << endl;
26
참고 : http://prostars.net/55
// 컴파일 오류 : 타입 변환을 할 수 없다.
// derived2 = base2;
// 컴파일 성공 : 런타임에 타입 변환에 성공하며
// Derived 타입의 포인터를 반환한다.
derived2 = dynamic_cast<Derived*>(base2);
if (derived2)
derived2->print();
// 컴파일 성공 : 이런 경우에는 캐스팅이 필요 없다.
derived2 = derived1;
27
#include <iostream>
#include <typeinfo>
using namespace std;
class Animal
{
virtual void something() { }
};
class Dog : public Animal { };
class Bird : public Animal { };
void speak(const Animal& animal) {
if (typeid(animal) == typeid(Dog&))
cout << "Woof!" << endl;
else if (typeid(animal) == typeid(Bird&))
cout << "Chirp!" << endl;
}
Dog dog;
Bird bird;
Animal& animal = dog;
speak(animal);
animal = bird;
speak(bird);
Woof!
Chirp!

C++ Programming - 12th Study

  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
    7 class Baz :public Foo, public Bar { // Something };
  • 8.
    8 class Dog { public: virtual voidbark() { cout << "Woof!" << endl; } }; class Bird { public: virtual void chirp() { cout << "Chirp!" << endl; } }; class DogBird : public Dog, public Bird { };
  • 9.
  • 10.
    10 class Dog { public: virtualvoid bark() { cout << "Woof!" << endl; } virtual void eat() { cout << "The dog has eaten." << endl; } }; class Bird { public: virtual void chirp() { cout << "Chirp!" << endl; } virtual void eat() { cout << "The bird has eaten." << endl; } };
  • 11.
    11 DogBird confusedAnimal; confusedAnimal.eat(); error C2385:ambiguous access of 'eat' note: could be the 'eat' in base 'Dog' note: or could be the 'eat' in base 'Bird' static_cast<Dog>(confusedAnimal).eat(); // 슬라이싱, Dog::eat() 호출 confusedAnimal.Dog::eat(); // 명시적으로 Dog::eat() 호출 void DogBird::eat() { Dog::eat(); // 명시적으로 Dog의 eat() 호출 }
  • 12.
    12 class Dog { public: virtual voideat() { cout << "The bird has eaten." << endl; } }; class Bird : public Dog {}; class DogBird : public Bird, public Dog {}; DogBird confusedAnimal; confusedAnimal.eat(); error C2385: ambiguous access of 'eat' note: could be the 'eat' in base 'Dog' note: or could be the 'eat' in base 'Dog'
  • 13.
    13 class Animal { public: virtual voidsleep() { cout << "Zzz..." << endl; } }; class Dog : public Animal { … }; class Bird : public Animal { … }; confusedAnimal.sleep(); error C2385: ambiguous access of 'sleep' note: could be the 'sleep' in base 'Animal' note: or could be the 'sleep' in base 'Animal
  • 14.
    14 class Animal { public: virtualvoid sleep() = 0; }; class Dog : public Animal { public: virtual void sleep() { … } }; class Bird : public Animal { public: virtual void sleep() { … } }; class DogBird : public Dog, public Bird { public: virtual void sleep() { Dog::sleep(); } };
  • 15.
    15 class Animal { public: virtual voidsleep() { cout << "Zzz..." << endl; } }; class Dog : public virtual Animal { … }; class Bird : public virtual Animal { … }; confusedAnimal.sleep(); // Animal이 virtual이기 때문에 모호하지 않음
  • 17.
    17 class Super { public: void go(){ cout << "Super::go()" << endl; } }; class Sub : public Super { public: void go() { cout << "Sub::go()" << endl; } }; Sub mySub; mySub.go(); Sub::go() Sub mySub; Super& ref; ref = mySub; ref.go(); Super::go()
  • 18.
  • 19.
    19 class Super { public: virtual voidfunc1() { } virtual void func2() { } }; class Sub : public Super { public: virtual void func2() { } }; Super mySuper; Sub mySub; vtable mySuper vtable mySub func1 func2 func1 func2 Super::func1() 구현부 Super::func2() 구현부 Sub::func2() 구현부
  • 20.
  • 21.
    21 class Super { public: Super(){ } ~Super() { } }; class Sub : public Super { private: char* mString; public: Sub() { mString = new char[30]; } ~Sub() { delete[] mString; } }; Super* ptr = new Sub(); // mString은 이 시점에 할당됨 delete ptr; // ~Super가 호출되었지만 // virtual이 아니기 때문에 // ~Sub는 호출되지 않음
  • 23.
  • 24.
    24 참고 : http://prostars.net/55 #include<iostream> using namespace std; class Base { public: virtual void print() { cout << "Base" << endl; } }; class Derived : public Base { public: virtual void print() { cout << "Derived" << endl; } };
  • 25.
    25 참고 : http://prostars.net/55 Base*base1 = new Base; Base* base2 = new Derived; Derived* derived1 = new Derived; Derived* derived2 = nullptr; // 컴파일 오류 : 타입 변환을 할 수 없다. // derived2 = base1; // 컴파일 성공 : 런타임에 타입 변환에 실패하며 // nullptr을 반환한다. derived2 = dynamic_cast<Derived*>(base1); if (derived2 == nullptr) cout << "Runtime Error" << endl;
  • 26.
    26 참고 : http://prostars.net/55 //컴파일 오류 : 타입 변환을 할 수 없다. // derived2 = base2; // 컴파일 성공 : 런타임에 타입 변환에 성공하며 // Derived 타입의 포인터를 반환한다. derived2 = dynamic_cast<Derived*>(base2); if (derived2) derived2->print(); // 컴파일 성공 : 이런 경우에는 캐스팅이 필요 없다. derived2 = derived1;
  • 27.
    27 #include <iostream> #include <typeinfo> usingnamespace std; class Animal { virtual void something() { } }; class Dog : public Animal { }; class Bird : public Animal { }; void speak(const Animal& animal) { if (typeid(animal) == typeid(Dog&)) cout << "Woof!" << endl; else if (typeid(animal) == typeid(Bird&)) cout << "Chirp!" << endl; } Dog dog; Bird bird; Animal& animal = dog; speak(animal); animal = bird; speak(bird); Woof! Chirp!