正在(在构造函数中)将其包含一个不良设计的指针传递,如果是的,则解决方案是什么

Is passing(in constructor) a pointer to class that contains it a bad design and if so what is the solution

本文关键字:指针 如果 是什么 解决方案 构造函数 不良 包含一 正在      更新时间:2023-10-16

经常我遇到

的代码
/*initializer list of some class*/:m_member(some_param,/* --> */ *this)

这样做的原因是m_member可以从包含它的类中调用成员函数...又名

//code in class that is m_member instance of
    m_parent->some_function();

我个人不喜欢它,因为我认为这是可悲的设计("亲爱的孩子,你知道你对班级封装做了什么"),但我想知道这种行为不好,如果是这样,如何避免这种设计。

编辑:请不要在Intorizer列表中关注此内容,可以说是在CTOR主体中。

可能是灾难性的,因为您的父构建参考集的时间。以下示例将证明这一点:

#include <iostream>
using namespace std;
struct TheParent;
struct TheChild
{
    TheChild(TheParent& parent);
    TheParent& myParent;
};
struct TheParent
{
    TheParent()
      : mychild(*this)
      , value(1)
    {
        cout << "TheParent::TheParent() : " << value << endl;
    }
    TheChild mychild;
    int value;
};
TheChild::TheChild(TheParent& parent)
   : myParent(parent)
{
    cout << "TheChild::TheChild() : " << myParent.value << endl;
};
int main()
{
    TheParent parent;
    return 0;
}

产生以下输出,显然注意到父对象的不确定状态:

TheChild::TheChild() : 1606422622
TheParent::TheParent() : 1

底线:不要这样做。您最好使用动态儿童分配,但即使是警告也是如此:

#include <iostream>
using namespace std;
struct TheParent;
struct TheChild
{
    TheChild(TheParent& parent);
    TheParent& myParent;
};
struct TheParent
{
    TheParent()
      : mychild(NULL)
      , value(1)
    {
        mychild = new TheChild(*this);
        cout << "TheParent::TheParent() : " << value << endl;
    }
    ~TheParent()
    {
        delete mychild;
    }
    TheChild* mychild;
    int value;
};
TheChild::TheChild(TheParent& parent)
   : myParent(parent)
{
    cout << "TheChild::TheChild() : " << myParent.value << endl;
};

int main()
{
    TheParent parent;
    return 0;
}

这为您提供了您可能想要的东西:

TheChild::TheChild() : 1
TheParent::TheParent() : 1

注意,但是,如果TheParent是继承链中的中级类,即使这也存在问题,并且您希望访问尚未构建的派生类中的函数的虚拟实现。

> 。

再次,最重要的是,如果您发现自己这样做,您可能想考虑为什么首先需要。

这是不好的,因为尚不清楚父类在构造m_member时的完整程度。

例如:

class Parent
{
   Parent()
   : m_member(this), m_other(foo)
   { }
};
class Member
{
    Member(Parent* parent)
    {
       std::cout << parent->m_other << std::endl; // What should this print?
    }
};

如果需要父级指针,则可以在构造函数的主体中使用" setparent"方法。

就像绝大多数编程实践一样,不可能说这是不好的(如果您这样做的话,您是一个坏人,应该惭愧)。我有时会使用它,但这并不常见。但是,这不是我试图通过更改班级设计故意避免的事情。

请注意我在上面段落中如何使用"我",这是一个肯定的迹象,这是一个高度主观的问题。

我将语言视为实现给定问题解决方案的工具。根据设计,C 允许明确使用this,而其他OO语言则不得。因此,我将语言功能视为工具箱中的工具,并且每隔一段时间都有一种使用一种工具。

但是,这就是编码风格和实践的出现,我应该知道我在做什么。我应该知道如何使用我的工具,我应该知道它们使用的含义。有一个定义的顺序,C 可以初始化一个新对象,只要我使用工作,我就很好。不幸的是,有时候人们很幸运。其他时候,他们以这种方式创建错误。您需要知道您的工具以及如何使用它们: - )

用我的个人意见回答您的问题:我试图避免这种特殊的结构,但有时我不得不使用它。即使是思考课程重新设计也无法避免。因此,我在这个场合提出了"嗯,有时我的设计无法以干净清洁的直oo进行建模,班级之间的依赖性太紧了,表现太多了。"

相关文章: