2011-03-08 92 views
0

如果我有几个级别的对象包含(一个对象定义和实例化另一个对象,它定义和实例化另一个对象..),是否有可能获取访问上层,包含 - 对象变量和函数,请问?从包含的对象访问包含对象的成员

实施例:

class CObjectOne 
    { 
    public: 
     CObjectOne::CObjectOne() { Create(); }; 

     void Create(); 

     std::vector<ObjectTwo>vObejctsTwo; 
     int nVariableOne; 
    } 
    bool CObjectOne::Create() 
    { 
     CObjectTwo ObjectTwo(this); 
     vObjectsTwo.push_back(ObjectTwo); 
    } 

    class CObjectTwo 
    { 
    public: 
     CObjectTwo::CObjectTwo(CObjectOne* pObject) 
     { 
     pObjectOne = pObject; 
     Create(); 
     }; 

     void Create(); 
     CObjectOne* GetObjectOne(){return pObjectOne;}; 

     std::vector<CObjectTrhee>vObjectsTrhee; 
     CObjectOne* pObjectOne; 
     int nVariableTwo; 
    } 
    bool CObjectTwo::Create() 
    { 
     CObjectThree ObjectThree(this); 
     vObjectsThree.push_back(ObjectThree); 
    } 

    class CObjectThree 
    { 
    public: 
     CObjectThree::CObjectThree(CObjectTwo* pObject) 
     { 
     pObjectTwo = pObject; 
     Create(); 
     }; 

     void Create(); 
     CObjectTwo* GetObjectTwo(){return pObjectTwo;}; 

     std::vector<CObjectsFour>vObjectsFour; 
     CObjectTwo* pObjectTwo; 
     int nVariableThree; 
    } 
    bool CObjectThree::Create() 
    { 
     CObjectFour ObjectFour(this); 
     vObjectsFour.push_back(ObjectFour); 
    } 

main() 
{ 
    CObjectOne myObject1; 
} 

说,从内CObjectThree我需要访问nVariableOneCObjectOne。我想如下做到这一点:

int nValue = vObjectThree[index].GetObjectTwo()->GetObjectOne()->nVariable1; 

然而,编译和运行我的应用程序后,我得到内存访问冲突错误

  • 上面的代码有什么问题(这是例子,可能包含拼写错误)?
  • 是否必须动态创建对象而不是静态
  • 是否有任何其他方式如何实现变量存储在包含对象从包含对象?
+1

您的代码不正确。所有类的所有成员都是私有的,所以这不会被编译。另外,你的类定义必须用分号结束。请张贴正确的,重现错误的工作代码。 – 2011-03-08 07:18:52

+0

@ Space_C0wb0Y:嗨,感谢您的评论。我会骗我的原始代码,但是,我已经分发了几个类文件。为了显示我的代码,我将不得不添加大量文本。我基本上对原理感兴趣,如果通过**引用包含对象,即使对象是静态创建的,这个**也应该可以工作。 – 2011-03-08 07:23:11

+1

如果你想要一个很好的答案,你将不得不在这个问题上做一些工作。这可能包括编写一个实际编译和复制错误的小示例应用程序。如果没有看到引起错误的实际代码,很难找到错误的原因。 – 2011-03-08 07:29:36

回答

1

当您传递指向容器对象的指针时,此指针有时称为返回指针。我发现这种技术一直在GUI库中使用,其中一个小部件可能需要访问其父部件。

这就是说,你应该问自己,是否有更好的设计,不涉及循环依赖关系(圆形的意思,容器取决于集装箱和集装箱取决于容器)。

您不要严格来说必须动态地创建对象,以便指针技术正常工作。您始终可以获取堆栈分配(或静态分配)对象的地址。 只要该对象的生命持续存在,而其他人正在使用它的指针。但实际上,这种技术通常与动态创建的对象一起使用。

请注意,您可能也可以使用反向引用而不是反向指针。


我想我知道是什么导致了你的分割错误。当你的向量重新分配它们的内存(由于增长到一个更大的大小),旧的向量元素的地址变得无效。但是这些东西的孩子们(和大孩子)仍然在他们的后台指针中保留着旧地址!

为了使反向指针工作,您必须动态分配每个对象并将它们的指针存储在向量中。这会使内存管理变得更加混乱,因此您可能需要使用智能指针或boost :: ptr_containers。


看到你另一个答案提出的意见后,我现在有你想要完成什么更好的主意。您应该研究通用树结构和复合图案。复合模式通常用在我之前引用的小部件示例中。

+0

@Emilie Cormier:+1有价值的答案。嗨Emilie,谢谢。你理解我的问题的重点。我需要知道这个例子在技术上是否可以接受。 **返回指针**和**返回参考**的术语对我来说是新的。我会更多地研究它。请问使用背向指针的反向引用有什么优势吗? – 2011-03-08 07:59:31

+0

@Bunkai:我纠正了我在答案中犯的一些错误,所以你可能想重新阅读它。当我累了时,我不应该回答问题。 :-) – 2011-03-08 08:17:27

+0

@Emilie Cormier:谢谢你的额外职位。是的,情况就是这样。那么,如果我超出了课程的范围,内存是否仍然可以访问?我知道std :: vector <>会随着它的增长而移动到不同的位置,但是我认为另一个想法是可访问范围外的对象。 – 2011-03-08 08:20:03

1

也许所有的对象都可以从像一个公共接口继承:

class MyObject 
{ 
public: 
    virtual int getData() = 0; 
} 

而后就可以用std ::树从STL库来构建结构。

+0

没有std :: tree这样的东西。 – 2011-03-08 07:50:47

+0

嗨克里斯,使用容器也可能是另一种可能性。我的应用程序处理文件目录结构,所以我的设计符合逻辑,因为它反映了目录和子目录的级联。如果我开始失去对我的设计的控制,我会切换到另一种设计。 – 2011-03-08 08:02:53

0

正如Emile所说,分段错误是由重新分配造成的。确切地说 - 当本地堆栈对象'this'指针被传递以创建另一个对象时,它将被复制到矢量容器中。然后'Create()'函数退出,堆栈框架对象停止存在,并且容器中的指针变得无效。