仮想消滅者、マルチプロパティ、抽象クラス、インタフェース、鋳造


非仮想消滅者

//Animal.h
class Animal
{
public:
	~Animal();
private:
	int mAge;
};

//Cat.h
class Cat : public Animal
{
public:
	~Cat();
private:
	char* mName;
};

//ex1 Cat
Cat* myCat = new Cat(2, "Coco"); //Cat.h 의 소멸자 호출 다음 부모 소멸자 호출 이상없음
delete myCat;

//ex2 업캐스팅 Cat
Animal* yourCat = new Cat(5, "Mocha"); //현재의 데이터 형이 Animal클래스이기때문에
delete yourCat;                        //바로 Animal class 소멸자만 호출.
																			 //자식클래스 소멸자 호출안되므로 mName 메모리누수

仮想消滅者

//Animal.h
class Animal
{
public:
	virtual ~Animal();
private:
	int mAge;
};

//Cat.h
class Cat : public Animal
{
public:
	virtual ~Cat();//여기는 virtual 키워드 생략해도됨. 혹시나 Cat 을 다시 상속받을수도있으니..
private:
	char* mName;
};

//Cat.cpp
Cat::~Cat()
{
	delete mName;
}
  • は、すべての消滅者に常に仮想キーワードを追加します.

  • because. コラボレーションの時に私が作ったクラスを引き継ぐ人がいるかもしれませんが、そうすると一つ一つコントロールできません...

    たけいせい



  • アップリンクは、異なるクラスを1つの配列に制御するのに役立ちます.
  • 複数の継承

    //Animal.h
    class Animal
    {
    };
    //Tiger.h
    class Tiger : virtual public Animal
    {
    };
    //Lion.h
    class Lion : virtual public Animal
    {
    };
    
    //Liger.h
    class Liger : public Tiger, public Lion
    {
    };
    //가상 베이스클래스로 상속받으면 해결 가능하지만 한번에 이런 구조를 만들지 않는이상 해결하기 어려운점이 있음.
    //해결책은 인터페이스를 통해서 해결가능.
    

    抽象クラス

  • の純粋な仮想関数を持つベースクラスを抽象クラスと呼ぶ.
  • 抽象クラスにオブジェクト
  • を作成できません.
  • 抽象クラスは、ポインタまたは参照クラス
  • として使用することができる.
    //Animal.h
    class Animal
    {
    public:
    	virtual ~Animal();
    	virtual void Speak() = 0;//순수 가상함수 : 구현체가 없는 멤버함수, 파생클래스가 구현해야함.
    private:
    	int mAge;
    };
    //Cat.h
    class Cat : public Animal
    {
    public:
    	~Cat();
    	void Speak();
    private:
    	char* mName;
    };

    インタフェース

  • c++自体はインタフェース
  • をサポートしていません.
  • の純粋な抽象クラスを使用してJavaのインタフェースを模倣する
  • 純仮想関数
  • のみ
  • メンバー変数なし//会社によってはメンバー変数が重ならないところもあります.
  • // IFlyable.h
    class IFlyable
    {
    public:
    	virtual void Fly() = 0;
    };
    //IWalkable.h
    class IWalkable
    {
    public:
    	virtual void Walk() = 0;
    };
    class Bat : public IFlyable, public IWalkable
    {
    public:
    	void Fly();
    	void Walk();
    };
    class Cat : public IWalkable
    {
    public:
    	void Walk();
    };

    明示鋳造

  • c++鋳造
  • static_cast
  • const_cast
  • dynamic_cast
  • reinterpret_cast
  • static_cast

    Animal* myPet = new Cat(2, "Coco");
    
    Cat* myCat = static_cast<Cat*>(myPet);
    
    Dog* myDog = static_cast<Dog*>(myPet);   //컴파일되지만 위험, Dog 클래스 멤버를
    myDog->GetDogHouseName();                //가지고있지 않기때문에 크래시가 날 수 있다.
    for example(static_cast cat to dog)
    //animal.cpp
    #include "Animal.h"
    
    namespace samples
    {
    	Animal::Animal(int age)
    		: mAge(age)
    	{
    	}
    }
    
    //cat.cpp
    #include <iostream>
    #include "Cat2.h"
    
    namespace samples
    {
    	const char* Cat2::mAnimalType = "Cat";
    
    	Cat2::Cat2(int age, const char* name)
    		: mAge(age)
    	{
    		mName = new char[strlen(name) + 1];
    		memcpy(mName, name, strlen(name) + 1);
    	}
    
    	Cat2::~Cat2()
    	{
    		delete[] mName;
    	}
    
    	// static function
    	const char* Cat2::GetType()
    	{
    		return mAnimalType;
    	}
    }
    
    //dog.cpp
    #include <cstring>
    
    #include "Dog.h"
    
    namespace samples
    {
    	Dog::Dog(int age, const char* address)
    		: Animal(age)
    	{
    		mHomeAddress = new char[strlen(address) + 1];
    		memcpy(mHomeAddress, address, strlen(address) + 1);
    	}
    
    	Dog::~Dog()
    	{
    		delete[] mHomeAddress;
    	}
    
    	const char* Dog::GetAddress() const
    	{
    		return mHomeAddress;
    	}
    }
    
    //static casting ex
    #include <iostream>
    
    #include "Animal.h"
    #include "Cat.h"
    #include "Dog.h"
    #include "ObjectPointerCastingExample.h"
    
    using namespace std;
    
    namespace samples
    {
    	void ObjectPointerCastingExample()
    	{
    		Animal* pet1 = new Cat(2, "Lulu");
    		Animal* pet2 = new Dog(2, "Burnaby");
    	
    		Cat* cat = static_cast<Cat*>(pet1);
    		Dog* dog1 = static_cast<Dog*>(pet2);
    		Dog* dog2 = static_cast<Dog*>(pet1);//이부분 cat to dog static casting
    
    		cout << "cat's name : " << cat->GetName() << endl;
    		cout << "dog1's address :" << dog1->GetAddress() << endl;
    
    		// prints cat's name instead
    		cout << "dog2's address : " << dog2->GetAddress() << endl;
    		//함수 리스트 테이블에서 상대적 위치가 같기때문에 이 함수들은 4바이트만큼 떨어진 곳에 있는 
    		//const char* 멤버 변수를 반환 즉 두 클래스의 변수 접근 위치가 같은 형태였기때문에 접근가능
    
    		delete pet1;
    		delete pet2;
    	}
    }

    reinterpret_cast


    ビットモードは変更されませんが、コンパイラが解釈するデータ型は変更されます.
    ret castの使い方を再解釈する

    const_cast

    void WriteLine(char* ptr);//뭔가 별로인 외부 라이브러리
    
    void MyWriteLine(const char* ptr) //우리프로그램
    {
    	WriteLine(const_cast<char*>(ptr));
    }
    //써드파티 라이브러리가 const를 제대로 사용하지 않을때

    dynamic_cast


    RTTIがオフの場合、static castと同様に動作します.
    通常、RTTIはc++プロジェクトでオフになります.(パフォーマンス...)

    鋳造規則

  • デフォルトでstatic castを使用
  • 再解釈体cast静的castではなくcast
  • CatがAnimalでない場合、コンパイラでエラーが発生します.
  • を使用して再解釈体cast
  • ポインタから非ポインタへの変換
  • は、実行(データシリアル化)が確実に必要な場合がある
  • .
  • 間の非相関ポインタ間の変換は、そのデータ型が正しいと判断する場合にのみ、
  • を行うことができる.
  • const castは、変更権限のない外部ライブラリを呼び出す場合にのみ使用されます.