这是一个基本的概念问题。如果我有一个继承自 Base 的 Derived 类,并且我实例化了一个新的 Derived 对象,我是否可以将它的 Base 对象设置为我选择的特定 Base 对象,以便所有调用基类方法都重定向到这个特定的基对象?
像这样的东西:
class Base
{
protected:
string name;
public:
Base(string n) { name = n}
void doSomething(){cout << name << "\n";}
};
class Derived : public Base
{
public:
Derived(string n) : Base(n) {}
int main()
{
Derived* d = new Derived("original base"); //create a derived
d->doSomething(); // prints "original base"
Base* rB = new Base("replacement base"); // create a new base object
((Base*) d) = rB; // replace the base object of d with a new one (pretend code)
d->doSomething(); // prints "replacement base"
return 0;
}
我确信我在那个简单的代码中犯了各种各样的错误,因为我的技能水平很低,但只是为了这个想法。
这在 C++ 中可能吗?我们可以将派生信息从一个对象中分割出来,那么我们可以分离和替换继承链中的组件吗?
我为什么要这样做?
考虑 mixin lilies:(再次原谅语法错误)
template <class T> class MyMixin : public T
{
public:
MyMixin(T desiredBaseObject)
{
// do something to set the desired base
// object of this class to desiredBaseObject.
}
};
RandomClass1 dog(int i = 0);
RandomClass2 cat(double i = 0.0);
MyMixin< RandomClass1 > mixin1(dog);
MyMixin< RandomClass2 > mixin2(cat);
在这种情况下,如果我们可以将 mixin 的基础对象设置为任何所需的对象,我们就可以在 mixin 中使用带有任何参数列表的构造函数,而 mixin 不需要知道任何关于它的信息。此外,mixin 可以像装饰器一样使用,而无需装饰器之间的通用接口。
感谢您的回答。由于我们可以分割对象的派生部分,因此基础信息和派生信息似乎是分开存在的。有人可以对此发表评论吗?我们能否访问一些内部表,比如我经常听到的 vtables(我对这种类型的东西一无所知,所以这可能不适用),并完成这个?
@Benoît
您能解释一下为什么只有 1 和 4 有效,而 2 和 3 无效吗?类 Base { 受保护:std::string 名称;公共:基础(标准::字符串 n){ 名称 = n;}
virtual void doSomething()
{
cout << name << "\n";
}
};
class Derived : public Base
{
public:
int x;
Derived(std::string n) : Base(n)
{
x = 5;
}
void printX()
{
cout << "x = " << x << "\n";
x++;
}
};
Derived* d1 = new Derived("original 1");
d1->doSomething();
d1->printX();
Base* rb1 = new Base("new 1");
*static_cast<Base*>(d1) = *rb1;
d1->doSomething();
d1->printX();
cout << "\n\n";
Derived d2 = Derived("original 2");
d2.doSomething();
d2.printX();
Base b2 = Base("new 2");
static_cast<Base>(d2) = b2;
d2.doSomething();
d2.printX();
cout << "\n\n";
Derived d3("original 3");
d3.doSomething();
d3.printX();
Base b3("new 3");
static_cast<Base>(d3) = b3;
d3.doSomething();
d3.printX();
cout << "\n\n";
Derived d4("original 4");
d4.doSomething();
d4.printX();
Base b4("new 4");
*static_cast<Base*>(&d4) = *&b4;
d4.doSomething();
d4.printX();
cout << "\n\n";
这将打印:
原来的 1 x = 5 新的 1 x = 6
原始 2 x = 5 原始 2 x = 6
原始 3 x = 5 原始 3 x = 6
原来的 4 x = 5 新的 4 x = 6
为什么这仅在使用指针时才有效?