关于指针降级/继承 所以我要完成PrATA的C++底漆,我是RTTI。他表现出一种悲观情绪,只是说这是错误的,但我想看到一个更好的例子 class Grand { private: int hold; public: Grand(int h=0) : hold(h) {} virtual void Speak() const { cout << "I am a grand class\n";} virtual int Value() const {return hold; } void Gah() const {cout << "ok" << endl;} }; class Superb : public Grand { public: Superb(int h = 0) : Grand(h){} void Speak() const {cout << "I am a superb class!!\n";} virtual void Say() const { cout << "I hold the superb value of " << Value() << "!\n";} void Sah() const { cout << "Noak" << endl;} }; class Magnificent : public Superb { private: char ch; public: int hour; Magnificent(int h = 0, char c = 'A') : Superb (h), ch(c){} void Speak() const {cout << "I am a magnificent class!!!\n";} void Say() const {cout << "I hold the character " << ch << "and the integer " << Value() << "!\n";} void Mah() const {cout << "Ok" << endl;} }; Grand * GetOne(); int _tmain(int argc, _TCHAR* argv[]) { /* srand(time(0)); Grand * pg; Superb * ps; */ Grand * pg = new Grand; Grand * ps = new Superb; Grand * pm = new Magnificent; Magnificent * ps2 = (Magnificent *)pg; ps2->Gah(); cout << ps2->hour << endl; system("pause"); } class-Grand { 私人: int hold; 公众: 大(inth=0):保持(h){} virtual void Speak()const{cout
只需将值设置为关于指针降级/继承 所以我要完成PrATA的C++底漆,我是RTTI。他表现出一种悲观情绪,只是说这是错误的,但我想看到一个更好的例子 class Grand { private: int hold; public: Grand(int h=0) : hold(h) {} virtual void Speak() const { cout << "I am a grand class\n";} virtual int Value() const {return hold; } void Gah() const {cout << "ok" << endl;} }; class Superb : public Grand { public: Superb(int h = 0) : Grand(h){} void Speak() const {cout << "I am a superb class!!\n";} virtual void Say() const { cout << "I hold the superb value of " << Value() << "!\n";} void Sah() const { cout << "Noak" << endl;} }; class Magnificent : public Superb { private: char ch; public: int hour; Magnificent(int h = 0, char c = 'A') : Superb (h), ch(c){} void Speak() const {cout << "I am a magnificent class!!!\n";} void Say() const {cout << "I hold the character " << ch << "and the integer " << Value() << "!\n";} void Mah() const {cout << "Ok" << endl;} }; Grand * GetOne(); int _tmain(int argc, _TCHAR* argv[]) { /* srand(time(0)); Grand * pg; Superb * ps; */ Grand * pg = new Grand; Grand * ps = new Superb; Grand * pm = new Magnificent; Magnificent * ps2 = (Magnificent *)pg; ps2->Gah(); cout << ps2->hour << endl; system("pause"); } class-Grand { 私人: int hold; 公众: 大(inth=0):保持(h){} virtual void Speak()const{cout,c++,C++,只需将值设置为ps2->hour,您的内存就会溢出-ps2分配的内存足以容纳Grand实例,这对于granium实例来说是不够的(因为它有更多的类变量) 试试这个实验: -分配一个Grand对象数组。 -将hold的值设置为某物 -通过强制转换,将hour的值设置为另一个值 -打印所有元素的hold值 -看看会发生什么…只要调用由实际使用派生类的数据成员的派生类实现的虚拟方法,它就会中断。现在您很幸运,Gah成员函数不涉及任何数据 下面是一个实际失败的示例,演示了C++中C风格强制转换的危险性:
ps2->hour
,您的内存就会溢出-ps2分配的内存足以容纳Grand
实例,这对于granium
实例来说是不够的(因为它有更多的类变量)
试试这个实验:-分配一个
Grand
对象数组。-将
hold
的值设置为某物-通过强制转换,将
hour
的值设置为另一个值-打印所有元素的
hold
值-看看会发生什么…只要调用由实际使用派生类的数据成员的派生类实现的虚拟方法,它就会中断。现在您很幸运,
Gah
成员函数不涉及任何数据
下面是一个实际失败的示例,演示了C++中C风格强制转换的危险性:
struct base
{
virtual ~base() {}
virtual void print() const { std::cout << "base" << std::endl; }
};
struct second_base // :)
{
virtual ~second_base() {}
virtual void second_print() const { std::cout << second << std::endl;
};
class derived: second_base, public base
{
std::string name_;
public:
explicit derived( const std::string& n ) : name_( n ) {}
virtual void print() const
{
std::cout << "derived: " << name_ << std::endl;
}
};
base* pbase( new base );
derived* pderived = ( derived* )pbase; // C-cast will allow this
pderived->print(); // BOOM!
研究并使用它们而不是C类型转换。始终!不要使用C类型转换。
它们并不安全。C++已经引入了4个新的模型,你所寻找的是动态的。
magnific*ps2=dynamic_cast(pg);//如果pg是一个magnific
//(或者是一个超级类的
//(宏伟)它工作得很好。
//如果pg不是一个华丽的(在本例中),它将返回NULL。
当您使用C样式转换时,您是在告诉编译器忽略所有规则并按您所说的去做(编译器很乐意这么做)。没有进行任何检查来确保您所做的是有意义的
<> > C++样式转换更为有限,每个都有特定的范围。动态Dype是用来上下类层次的。现在,请理解它,但是上面的示例运行了基础打印而不是派生的打印……即使是虚函数……是的,在发布后实现了。e表示多重继承,其中
base
不是第一个基类。
base* pbad( new base );
base* pgood( new derived( "humppa" ));
derived* pfails( dynamic_cast<derived*>( pbad ));
derived* pworks( dynamic_cast<derived*>( pgood ));
if ( pfails ) pfails->print(); // no cookie
if ( pworks ) pworks->print(); // prints "derived: humppa"
Magnificent * ps2 = dynamic_cast<Magnificent*>(pg); // If pg is a Magnificent
// (or is a super class of
// Magnificent) it works fine.
// If pg is not a Magnificent (in this case) it will return NULL.