我 C++玩的不怎么样。尤其是继承。所以想多学习学习。
有一个基类对象,我想在它上面加一部分功能,就做了一个派生类(但派生类没法做到完美继承基类,因为其中基类有一堆的注册函数,搞定太复杂)。
于是,我就想,通过派生类指针 + 基类的对象,来实现功能的添加。
我试了但是不工作不了
#include <iostream>
#include <string>
#include <memory>
using std::string;
using std::cout;
using std::endl;
using std::shared_ptr;
class Base {
public:
Base(const char * str): token(str) {}
virtual void addComment() { token+="is the most beautiful language!"; }
void speakOut() const { cout<<token<<endl; }
protected:
string token;
};
class Derived: public Base {
public:
Derived(const char* str): Base(str) {}
void addComment() { token="Python is the most beautiful language!"; }
};
int main() {
// ----- base_ptr call base_object -----
shared_ptr<Base> ptr_base_obj(new Base("C++"));
ptr_base_obj->addComment();
ptr_base_obj->speakOut();
// ----- derived_ptr call derived_object -----
shared_ptr<Derived> ptr_derived_obj(new Derived("PHP"));
ptr_derived_obj->addComment();
ptr_derived_obj->speakOut();
// ----- derived_ptr call base_object -----
shared_ptr<Base> ptr_base_obj2(new Base("PHP"));
// downcasting base to derived ptr
shared_ptr<Derived> ptr_derived_obj2 = std::dynamic_pointer_cast<Derived>(ptr_base_object2);
ptr_derived_obj2->addComment();
ptr_derived_obj2->speakOut();
return 0;
}
执行结果:
C++ is the most beautiful language!
Python is the most beautiful language!
Segmentation fault
想问,到底该怎么做,才能实现这个的需求。
另外,谁能把代码中 PHP is the most beautiful language!给输出出来?
1
secondwtq 2017-06-19 22:07:50 +08:00 2
暂时没试,不过发现几个问题:
1. 我在你 po 出的代码里找不到 ptr_base_object2 这个 symbol。 2. 要是想玩 hack 就不要用 dynamic_cast,无论楼主提出的命题是否成立,dynamic_cast 在作用于指针参数时遇到 cast 失败的情况都会返回 nullptr (作用于引用参数时抛出 std::bad_cast ),也就是楼主这个 segfault 是必然的。 3. 标准应该是把这种行为定义为 UB 的,一般实现中应该是可以的(如果你非要从底层的角度抠的话),不过别干在派生类方法中访问派生类成员这种事情,其实你这种行为本来就不应该有,本身是 UB 不说,实际也很容易玩脱的。 具体来说,ctor/dtor 这种机制是 C++ 对象语义中非常必要的东西,有了这一套对象语义才有了 RAII 等 C++ 最独特的特性( Herb Sutter 说过 Java 等处理的是 Garbage,C++ 处理的是 Object ),楼主为了方便直接把这些东西全给 compromise 了,实在不是值得鼓励的做法。 |
2
xss 2017-06-20 09:42:47 +08:00 1
speakOut 作为 virtual 方法
这个是多态的典型应用场景 |