除了修改所有派生类之外,我无法找到问题的解决方案。
我有一个Base
类和一些继承自Derived
的{{1}}个类。现在,还有另一个班级Base
,其中包含Container
类指针Base
的向量。
上面的列表在创建后填充了所有派生类对象的地址。
所有文件都在不同的翻译单元中。
我想做什么:
std::vector<Base *> derivList
能够使用Container中指向不同派生类的vector元素从1)
类调用Base
类的单个函数。
Container
但是当我调用这个函数时,在该函数中我应该能够访问2)
类指针所在的public members
类的Derived
指着。
Base
我的约束是:
class Base
{
public:
virtual void someMethod();
void containerCallsThisMethod();
};
void Base::containerCallsThisMethod()
{
// I need to access the public functions of derived classes here
// say: Derived1::calc(), Derived2::calc,.( I don't have derived class names here in Base)
}
class Derived1:public Base
{
public:
void calc();
};
class Container
{
std::vector<Base *> derivList;
void execute();
};
void Container::execute()
{
for(i = 0; i < derivList.size();i++)
{
derivList[i]->containerCallsThisMethod();
}
}
课,因为它非常费力,但我仍然可以更改Derived
课程。Base
不能拥有Base
类的列表(甚至不是前向声明)。我认为我可以通过Derived
指针执行此操作,因为它具有this
函数的ClassName
类型,并且它指向派生类对象。但我无法使用non-const
调用Derived
类方法。
有没有办法在没有太多劳动力,任何具体设计模式或黑客的情况下做到这一点?
答案 0 :(得分:0)
如果您有一个带派生类的基类,这些派生类会覆盖该函数,让我们调用它func()
,然后调用func()
的覆盖。就我所知,你想要的唯一解决方案是继承派生类的良好行为或将func()
作为静态函数,将其放入友元类,或者将其放入静态内部类中
答案 1 :(得分:0)
如果我理解正确,您可以在calc
中将protected
声明为(可能是Base
)虚拟函数。仅当calc
在所有派生类中具有完全相同的签名时,此方法才有效。在这种情况下,不必在派生类中更改代码。现在,当您在this->calc
中致电Base
时,它将被发送到Derived
中的实施。
class Base
{
public:
vitrual void someMethod();
void containerCallsThisMethod();
virtual ~Base(); // Important !!
protected:
virtual void calc() = 0;
};
void Base::containerCallsThisMethod()
{
calc(); // will call derived class implementation
}
请记住在执行此操作时向Base
添加虚拟析构函数。
这是有效的,因为当一个方法声明为虚拟时,它也将在所有派生类中都是虚拟的,即使没有明确指定。
答案 2 :(得分:0)
如果
不同派生类的公共成员
您需要访问具有相同签名的方法,但在每个派生类中实现的方式不同(这是您的示例所示),您只是发现自己处于最基本的用例虚拟方法绑定。
然后你会非常幸运:你只需要在 Base 类定义中的方法签名之前添加virtual关键字。
class Base
{
void containerCallsThisMethod()
{
calcDerivedMethod();
}
virtual void calcDerivedMethod();
}
class DerivedA : public Base
{
void calcDerivedMethod()
{
//Specific implementation for DerivedA class.
}
}
这里发生的正是您所描述的要求: 容器方法执行()在它指向的每个对象上依次调用 containerCallsThisMethod()。此调用最终始终为 Base :: containerCallsThisMethod()。但是在最后一个方法中,对 calcDerivedMethod()的调用被分派到指针的动态类型(即Derived类)。只需在基础中的 calcDerivedMethod()声明前添加虚拟关键字,即可获得此动态调度。