C++入门(16):副本构造器和赋值操作符、强制类型转换
副本构造器和赋值操作符
副本构造器形式为:MyClass(const MyClass &rhs);
,没有返回类型。
赋值操作符形式为:MyClass &operator=(const MyClass &rhs);
只要声明了一个有指针属性并将在析构器里释放那块内存的类,就需要实现一个副本构造器和一个赋值操作符,两者缺一不可。
一定要保证副本构造器对所有的属性(而不仅仅是指针)都进行了复制。
动态对象强制类型转换
dynamic_cast<MyClass*>(value)
:用来把一种类型的对象指针安全地强制转换为另一种类型的对象指针;
如果 value 的类型不是一个 MyClass 类(或 MyClass 的子类)的指针,这个操作符将返回NULL。
C++中高级强制类型转换操作符
const_cast<MyClass*>(value)
:用来改变 value 的常量性;
dynamic_cast<MyClass*>(value)
:动态对象强制类型转换;
reinterpret_cast<T>(value)
:在不进行任何实质性转换的情况下,把一种类型的指针解释为另一种类型的指针或是把一种整数解释为另一种整数;
static_cast<T>(value)
:用来进行强制类型转换而不做任何运行时检查,老式强制类型转换的替代品。
下面是动态对象强制类型转换的代码示例:
#include <iostream>
#include <string>
class Pet{
public:
Pet(std::string name);
virtual ~Pet() ;
virtual void eat();
virtual void play();
protected:
std::string name;
};
class Dog:public Pet{
public:
Dog(std::string name, int count);
~Dog();
void play();
void bark();
private:
int count;
};
Pet::Pet(std::string name)
{
this->name = name;
}
Pet::~Pet()
{
std::cout << " It's Pet's destructor...\n";
}
void Pet::eat()
{
std::cout << name << " is eating..." << std::endl;
}
void Pet::play()
{
std::cout << name << " is playing..." << std::endl;
}
Dog::Dog(std::string name, int count):Pet(name)
{
this->count = count;
}
Dog::~Dog()
{
std::cout << " It's Dog's destructor...\n";
}
void Dog::play()
{
std::cout << name << " plays " << count << " times a day..." << std::endl;
}
void Dog::bark()
{
std::cout << name << " is barking..." << std::endl;
}
Pet *CreatePet(std::string name, int count = 0);
int main(int argc, char** argv) {
Pet *pet = CreatePet("LS1") ;
pet->eat();
pet->play();
delete pet;
pet = NULL;
pet = CreatePet("LS2",3);
Dog *dog = dynamic_cast<Dog*>(pet); //动态对象强制类型转换
if(dog != NULL) //在继续操作之前检查它的结果是不是NULL
{
std::cout << "Casted successfully!" << std::endl;
dog->play();
dog->bark();
}
else
{
std::cout << "It's not a legal type!" << std::endl;
}
delete pet;
pet == NULL;
return 0;
}
Pet *CreatePet(std::string name, int count /* = 0 */)
{
if(count <= 0)
{
return new Pet(name); //创建并返回一个新的Pet实例
}
else
{
return new Dog(name, count); //创建并返回一个新的Dog实例,。这是允许的,因为Dog是Pet的一个子类,即可以说成,每个Dog都是一个Pet
}
}
运行结果为:
LS1 is eating...
LS1 is playing...
It's Pet's destructor...
Casted successfully!
LS2 plays 3 times a day...
LS2 is barking...
It's Dog's destructor...
It's Pet's destructor...