正在(在构造函数中)将其包含一个不良设计的指针传递,如果是的,则解决方案是什么
Is passing(in constructor) a pointer to class that contains it a bad design and if so what is the solution
经常我遇到
的代码/*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进行建模,班级之间的依赖性太紧了,表现太多了。"
- 如果基类包含双指针成员,则派生类的构造函数
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 如果非动态变量被指针引用,何时超出范围?
- 如果整数与指针大小相同,则重新解释将整数转换为指针双射是否具有双射作用?
- 如果我在指针中使用 ++ 操作数,我的值就会出错
- 在C++中,如果我可以直接将整数分配给指针而不使用"new",为什么要使用"new"?
- 如果我在 const 函数上使用指针,我可以返回什么?
- 如果只有 std::auto_ptr 可用,我是否仍应该使用智能指针?
- 如果我删除指针,我的C++程序会意外删除系统文件吗?
- 如果类"A"具有指向另一个类的指针,则"B" A 可以访问 B 类公共方法
- C++我们可以取消引用此指针吗?如果是这样,那么如何,如果不是,那为什么?
- 如果函数采用指向类的指针,则函数将完全脱离候选列表
- 如果我们不创建一个新节点并使用指针插入数据并建立链接(在链表中)怎么办?
- 如果我知道只会使用现有元素,我可以在数组开头之前传递指针吗?
- 我可以直接为指针分配地址吗?如果是,如何做到这一点
- 如果模板中存在成员函数指针,如何获取该指针
- Segfault如果更改派生类的指针值
- 返回列表元素的指针(如果具有相同的名称)
- 智能指针——如果构造函数抛出怎么办?