Это основной концептуальный вопрос. Если у меня есть класс, который является производным, который наследуется от Base, и я создаю экземпляр нового объекта Derived, могу ли я установить его базовый объект для определенного объекта 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 ++? Мы можем вырезать полученную информацию из объекта, поэтому можем ли мы отделить и заменить компоненты в цепочке наследования?
Зачем мне это делать?
Рассмотрим миксиновые лилии: (опять же, простите за синтаксические ошибки)
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);
В этом случае, если бы мы могли установить базовый объект миксина для любого желаемого объекта, мы могли бы использовать конструкторы с любым списком параметров в нашем миксине, при этом микшину не нужно было ничего о нем знать. Кроме того, миксин может использоваться как декоратор без необходимости использования общего интерфейса для декораторов.
Спасибо за ответы. Поскольку мы можем отрезать производную часть объекта, кажется, что база и производная информация живут отдельно. Может ли кто-нибудь прокомментировать это? Можем ли мы получить доступ к какой-нибудь внутренней таблице, например к vtables, о которой я так много слышал (я ничего не знаю об этом типе вещей, так что, возможно, это не применимо), и выполнить это?
@ * Benoît 1019 *
Не могли бы вы объяснить, почему только 1 и 4 работают, а 2 и 3 - нет?
базовый класс
{
защищенный:
std :: string name;
общественности:
База (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
х = 5
новый 1
х = 6
оригинал 2
х = 5
оригинал 2
х = 6
оригинал 3
х = 5
оригинал 3
х = 6
оригинал 4
х = 5
новый 4
х = 6
Почему это работает только при использовании указателя?