gpt4 book ai didi

c++ - 初始化派生类的安全方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:04 24 4
gpt4 key购买 nike

我有一个基类:

class CBase {
public:
virtual void SomeChecks() {}
CBase() {
/* Do some checks */
SomeChecks();
/* Do some more checks */
}
};

和派生类:

class CDerived : public CBase {
public:
virtual void SomeChecks() { /* Do some other checks */ }
CDerived() : CBase() {}
};

这个构造似乎有点奇怪,但在我的例子中这是必需的,因为 CBase 会做一些检查,而 CDerived 可以在它们之间混合一些检查。您可以将其视为在构造函数中“ Hook ”函数的一种方式。这种构造的问题在于,在构造 CDerived 时,首先构造 CBase 并且不知道 CDerived(因此未调用重载函数 SomeChecks())。

我可以这样做:

class CBase {
public:
void Init() {
/* Do some checks */
SomeChecks();
/* Do some more checks */
}
virtual void SomeChecks() {}
CBase(bool bDoInit=true) {
if (bDoInit) { Init(); }
}
};
class CDerived : public CBase {
public:
virtual void SomeChecks() { /* Do some other checks */ }
CDerived() : CBase(false) { Init() }
};

这不是很安全,因为我希望带有 false 参数的构造函数受到保护,因此只有派生类才能调用它。但随后我必须创建第二个构造函数( protected )并使其采用其他参数(可能未使用,因为在不必调用 Init() 时调用了构造函数)。

所以我被困在这里了。

编辑其实我想要这样的东西:

class CBase {
protected:
void Init() { /* Implementation of Init ... */ }
CBase() { /* Don't do the Init(), it is called by derived class */ }
public:
CBase() { Init(); } // Called when an object of CBase is created
};
class CDerived : public CBase {
public:
CDerived() : CBase() { Init(); }
};

在我看来,不可能有 2 个具有相同参数的构造函数被保护和公开?

最佳答案

不允许在构造函数/析构函数中调用虚方法。
虽然这背后的过程是虚拟方法正在调用方法的最派生版本,如果构造函数尚未完成,则最派生数据尚未正确初始化,因此这样做可能会提供使用无效对象的机会。

你要找的是PIMPL设计模式:

class CBase { ... };
class CDerived: public CBase { ... }

template<typename T>
class PIMPL
{
public:
PIMPL()
:m_data(new T)
{
// Constructor finished now do checks.
m_data->SomeChecks();
}
// Add appropriate copy/assignment/delete as required.
private:
// Use appropriate smart pointer.
std::auto_ptr<T> m_data;
};
int main()
{
PIMPL<CDerived> data;
}

关于c++ - 初始化派生类的安全方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1425695/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com