从父指针访问子数据
Accessing child data from parent pointer
假设我有一个我无法更改的父班,并且它具有孩子将使用的函数。这两个孩子相似,但使用不同的数据。在此示例中,假设一个包含一个带有关联方法的数组,另一个包含一个带有关联方法的2D数组。
struct Parent {
Parent* DoSomethingWithChildren(Parent &other)
};
struct Child1 : Parent {
int a[x];
};
struct Child2 : Parent {
int b[x][y];
};
现在说我创造了两个孩子。
Parent* child1 = new Child1();
Parent* child2 = new Child2();
child1.DoSomethingWithChildren(child2);
dosomethingwithChildren函数应该能够使用" this"指针访问Child1,如果我没记错的话,并且由于Child2被传递给该功能,也应该可以访问。
问题在于,在dosomethingwithchildren函数中,我只能从父访问数据和功能。
有什么办法可以做到这一点吗?也许使用模板?
您的问题有几个解决方案。
动态铸造
class Parent {
public:
Parent* DoSomethingWithChildren(Parent& other) {
Child* childPointer = dynamic_cast<Child>(&other);
if(childPointer) {
// now you have Child class API
} else {
// this was clearly not a Child object
}
}
};
虚拟方法只需查找它们;)
,但我主要认为您的概念是错误的。这样做会更好:
class Parent {
virtual void doSomethingWithParent(Parent* parent) = 0;
};
class Child1 : public Parent {
void doSomethingWithParent(Parent* parent) {
//you now have Child1 API and parent object
}
};
int main() {
Parent parent;
Child1 child;
Child2 child2;
child1.doSomethingWithParent(parent);
child2.doSomethingWithParent(parent);
}
这样,每个孩子都可能有不同的过载。
派生的类应实现细节,而不是基本类以管理所有派生的类别。这简直是很差的。
您正在创建指向基类的指针,并在将构造函数用于其继承类之一时创建新的内存。当您调用属于基类的函数以使用其派生的类之一来完成某些派生类可以访问该基类的受保护或公共成员变量和功能的函数时,编译器可能不知道要明确工作哪种类型。如果您确切地知道您将拥有多少种不同的派生类型,那么在您的基类中,您可以对每种类型进行公开枚举,并将其作为私人成员存储。这是一个示例:
class Node {
public:
enum TYPE {
TYPE_ONE,
TYPE_TWO,
};
private:
TYPE m_type;
public:
explicit Node( Node::TYPE type ) : m_type( type ) {}
Node* doSomeWork( Node* other );
}; // Node
Node* Node::doSomeWork( Node* other ) {
Node* pNode = dynamic_cast<Node*>( other );
switch ( m_type ) {
case TYPE_ONE: {
// Do Work Here
return pNode;
}
case TYPE_TWO: {
// Do Work Here
return pNode;
}
default: {
// If derived type not defined either throw exception
// or return a nullptr
return pNode = nullptr;
}
}
}
class Type1 : public Node {
// Member Variables Here
public:
Type1() : Node( TYPE_ONE ) {}
};
class Type1 : public Node {
// Member Variables Here
public:
Type2() : Node( TYPE_TWO ) {}
};
在此示例中,当您调用您的函数进行工作时,将根据类型做出决定,并将派生类型的指针施放在基本类型工作的指针上,然后返回指针。
如果您确切知道自己拥有多少个派生类型,这将起作用。如果派生类型的数量未知,那么我建议在基类中纯粹将Dowork函数声明为虚拟函数,这使得基类使您无法创建它的实例,并且任何派生的类都必须实现纯粹是虚拟的功能,您可以让每个类覆盖它。
class Node {
public:
virtual ~Node(){}
virtual Node* doSomeWork( Node* other ) = 0;
protected:
Node(){}
};
class Type1 : public Node {
public:
// Must Be Implemented But Can Be Override
Node* doSomeWork( Node* other ) override;
};
class Type2 : public Node {
public:
// Must Be Implemented But Can Be Override
Node* doSomeWork( Node* other ) override;
};
Dynamic_cast的概念仍然适用于您的DosomeWork()函数,但是由于实现在类实现上实现,因此不需要开关语句!这样做任何派生类都必须声明并实现此功能。现在,如果特定的派生类型对此功能没有用,您仍然必须定义它,但是您将使身体的内容留为空。
- 用于访问容器<T>数据成员的正确 API
- 使用指针访问数组中的对象数据成员
- 友元函数无法访问私有数据成员 (c++)
- OpenCV C++ 3 维垫数据访问错误值
- 用于随机数据访问的最有效文件类型
- 用于多维数据访问的重载 () 运算符
- MEX C++原始数据访问
- C++数据访问基准
- 随机 mmaped 内存访问比堆数据访问慢 16%
- 共享内存多线程和数据访问
- 如何使用常见的C 业务逻辑和数据访问层构建跨平台移动应用程序
- 链表数据访问
- OpenMP线程、数据访问延迟和STL数据容器
- C++ 矢量数据访问
- 我很难在C++类中实现我想要的数据访问
- 概括模型中的数据访问.避免宏观的方法
- 矢量化/优化循环,用于宽寄存器(特别是Xeon Phi)的未对齐数据访问
- 松类耦合和数据访问
- 在Linux上锁定对单个进程内数据访问的最快方法
- 如何使用数据访问对象进行序列化和关系数据库数据访问