【发布时间】:2017-01-16 19:54:12
【问题描述】:
看似简单的事情一直是我当前的绊脚石。我有简单的继承,但我想确保在构造任何派生类型之前至少存在一个基类实例:
class Parent {
private:
std::string name_;
explicit Parent( const std::string& name );
protected:
// Constructor that Derived Types Will Use
Parent( const std::string& parentName, const std::string& childName, bool isChildAParent = false );
};
Child : public Parent {
public:
Child( const std::string& parentName, const std::string& childName, bool isChildAParent = false );
};
// It is here in the 2nd or protected constructor that I'm struggling with.
Parent::Parent( const std::string& parentName, const std::string& childName, bool isChildAParent ) {
// How To Go about to check if an instance of Parent already exists that
// used its default constructor before using this constructor from a derived type?
}
主要的用法是这样的:
int main() {
Child child( "parent", "child", false ); // Invalid since Parent wasn't created first
Parent parent( "parent" );
Child child( "parent", "child", false ); // Okay since parent exists.
return 0;
}
编辑 - 基于Kerrek SB 的评论说明
我可能在某处需要一个静态成员
这就是我现在所做的,我得到了我所期望的行为。
.h
class Parent {
private:
std::string myName_; // Name of this parent
static bool isConstructed_;
bool isParent_;
protected:
std::string parentName_;
public:
// This must be called first at least once before trying to create any children classes.
// The importances of this dependence has to do with the pointer of this parent being stored
// in a vector (outside of this class), and every child created after this will create a family that belongs to this parent.
explicit Parent( const std::string& name );
Parent( Parent &&self );
Parent& operator=( Parent &&transfer );
Parent( Parent const & ) = delete;
Parent& operator=( Parent const & ) = delete;
//*virtual*/ void print() { }
virtual void printName() const;
virtual void printParentName() const;
const std::string& getName() const;
const std::string& getParentName() const;
protected:
// Constructor that is used when using inheritance.
explicit Parent( const std::string& parentName, const std::string& childName, bool isChildAParent = false );
};
class Child : public Parent {
public:
Child( const std::string& parentName, const std::string& childName, bool isChildAParent = false );
};
.cpp
bool Parent::isConstructed_ = false;
// Initial Constructor Must Be Called First At Least Once.
Parent::Parent( const std::string& parentName ) :
myName_( parentName ) {
isConstructed_ = true;
isParent_ = true;
}
// Protected Constructor Used By Child Classes.
Parent::Parent( const std::string& parentName, const std::string& childName, bool isChildAParent ) {
// First check to see if this child will be a parent itself
if ( !isConstructed_ ) {
std::cout << "There must be at least 1 instance of a Parent\n"
<< "before constructing a child.\n";
} else {
myName_ = childName;
parentName_ = parentName;
isParent_ = isChildAParent;
}
}
// Move Constructor
Parent::Parent( Parent&& self ) {
}
// Move Opeartor
Parent& Parent::operator=( Parent&& self ) {
if ( this != &self ) {
}
return *this;
}
void Parent::printName() const {
std::cout << myName_ << std::endl;
}
void Parent::printParentName() const {
std::cout << parentName_ << std::endl;
}
const std::string& Parent::getName() const {
return myName_;
}
const std::string& Parent::getParentName() const {
return parentName_;
}
Child::Child( const std::string& parentName, const std::string& childName, bool isChildAParent ) :
Parent( parentName, childName, isChildAParent ) {
}
main.cpp - 第一个版本
int main() {
Parent p( "someParent" );
Child c( "someParent", "someChild" );
// Child's Construction is successful because Parent p exists
return 0;
}
main.cpp - 版本 2
int main() {
Child c( "someParent", "someChild" );
// Still compiles and prints out the message that a parent needs to exists first
// This can be thrown as an exception to prevent the creation
// of a derived type without at least having a base type that already exists.
return 0;
}
谢谢Kerrek SB。
编辑 -- 在考虑了我需要的 Parent 和 Child 类之间的关系之后,我想我得出的结论是,拥有另一个类可能会更好将是一个Abstract Base Class,Parent 和Child 类型将彼此独立地继承。这样,我的 Manager 或 Storage 具有这些容器的类将接受 shared_ptr<base_class> 以便它可以容纳任何一种类型,然后这些继承的类 Parent 和 Child 可以包含 references to pointers 的列表与它们相关联的那些。然后由Manager 或Storage 类负责检查其容器中的第一个条目是否实际上是Parent 类型而不是Child 类型。我继续将此添加到原始问题中,以供将来参考。我仍然希望对我刚才提到的上述构造提供一些反馈。
【问题讨论】:
-
你可能需要一个静态成员。
-
这对我来说就像一个XY Problem,你实际上想解决什么问题?
-
如果你改变
Child的构造函数需要一个Parent的引用,你可以确定存在一个Parent -
只知道
Parent已创建是没有意义的。如果有实际原因,那么Child必须有某种方式与Parent通信。那么假设有这种方式,为什么不能检查实际状态呢? -
当你创建一个子类时,必须创建父类,当然,但它们都是同一个对象的一部分。您正在询问一个单独的 Parent 对象。由于这是一种非常规的继承用法,我真的认为您应该展示实际的用例,而不是寻找特定的 hack。我很高兴您的问题得到了解答,但我认为如果您描述了实际问题,您本可以得到可以进一步改进您的解决方案的答案。
标签: c++ inheritance instance