C++正在更改子类中拥有的对象类型
C++ Changing owned object type in child class
我们有四个类:A、B、X和Y。B从A继承,Y从X继承。A的每个实例都创建一个类型为X的所属对象。一些伪代码:
class A {
protected:
X * OwnedObject;
}
class B : public A {
B();
void BFunction();
};
B::B() {
OwnedObject = new Y();
}
B::BFunction() {
OwnedObject -> YFunction(); //error, class A has no member named 'YFunction()'
}
class X {};
class Y : public X {
void YFunction(); //this function is new, it is not in X
};
B、 当然,继承了指向X的指针。如果我们希望B创建(及其指向的OwnedObject指针)子类Y的对象,而不是父类X的对象,该怎么办?解决这个问题最正确的方法是什么?
编辑:很抱歉,如果我不清楚,我添加了更多的伪代码,以更具体地说明我遇到的问题和我想做什么。感谢迄今为止的输入!
我可以想到两种不同的方法。
在第一个例子中,我假设类X可以知道其子类可能更改/实现的函数,但它(X)本身并不知道确切的实现。在这种情况下,我在X中有一个virtual
函数,根据是否有可能从X实例化,有两个实现:
// this X can not be instantiated
class X{
public:
virtual void f() = 0;
}
class Y : public X{
public:
virtual void f() { stuff to do; }
}
或者:
// this X can be instantiated
class X{
public:
virtual void f() { };
}
class Y : public X{
public:
virtual void f() { stuff to do; }
}
或者在另一个场景中,我假设因为B
是从Y
实例化的,所以它知道它是从Y
实例化的,因此它可以安全地将其转换为Y
,无论何时它想使用它:
B::BFunction() {
static_cast<Y*>(OwnedObject) -> YFunction();
}
或者,如果你想安全起见:
B::BFunction() {
if (dynamic_cast<Y*>(OwnedObject) != null)
static_cast<Y*>(OwnedObject) -> YFunction();
}
有点像这样吗?
class A {
protected:
A(X *x) : OwnedObject(x) {
// code...
}
X * OwnedObject;
}
class B : public A {
public:
B() : A(new Y()) {
// code...
}
};
我刚刚向A
添加了从任何子类注入X
对象的可能性
adrin的static_cast解决方案可能是您能做的最简单的事情。您只需要确保OwndedObject始终是Y的实例(而不是X或它的另一个子类)。
您可以在运行时检查(请参阅adrin的答案中的dynamic_cast,但使用dynamic_cast的结果,而不是添加另一个static_cast)。
B::BFunction() {
if (Y* y = dynamic_cast<Y*>(OwnedObject))
y->YFunction();
}
或者,您可以声明指针const(指针,而不是指针对象!星号后面的"const"关键字),并在构造函数中初始化它(ichramm的答案)。然后,您只需要查看A和B的构造函数,就可以推断您的static_cast是安全的。
您可以通过模板配置OwnedObject的类型。受此启发:http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern.
或者,与其将指针存储在基类中,不如创建一个虚拟成员函数来提供对它的读取访问:
class A_interface {
public:
virtual X* getX() = 0;
};
class A: public A_interface {
X* OwnedObject;
public:
virtual X* getX() {return OwnedObject;}
};
// B is no subclass of A anymore, because you don't want that X* member.
class B: public A_interface {
Y* OwnedObject;
public:
virtual X* getX() {return OwnedObject;}
};
根据设计,你不能在a_interface中有一个setX(X*)虚拟成员函数,因为你不能在B中实现它。http://en.wikipedia.org/wiki/Covariance_and_contravariance_(计算机科学)
- 是否可以获取成员函数模板参数的拥有对象?
- 拥有或在对象之间共享资源
- googlemock-如何模拟被测试类所拥有的对象
- C++ shared_ptr调用拥有对象的解构函数
- 在另一个 QThread 上运行成员方法时,无法将事件发送到其他线程拥有的对象
- 使用 lambda/std::function 删除拥有该函数的对象
- QT:QT无法将事件发送到另一个线程拥有的对象 - 原因
- 当 std::unique_ptr 在手动删除其拥有的对象后超出范围时,它如何工作?
- 谁拥有QQMlinCubator返回的对象
- 带有 std::map 的 c++ 结构是拥有动态数据对象的好设计吗?
- 是否可以使用对shared_ptr拥有的对象的引用
- 将原始指针向量清除给由独特指针拥有的对象
- 如何将 QEvent 传递给接收者拥有的对象?
- 如何正确地使一个对象拥有另一个多态对象
- C++拥有持久对象的最佳方式
- 将类的实例传递给另一个构造函数,该构造函数将其对象添加到所传递实例所拥有的列表中
- C++正在更改子类中拥有的对象类型
- 如何将此的shared_ptr返回给拥有它的对象
- 类同时拥有和共享对象
- 如何根据模板类型拥有对象向量