C++;/限制类的实例,其他哪些类从该实例继承 我想在C++中生成一个类,其他类继承它。但是我想确保没有人能够从这个类中创建实例

C++;/限制类的实例,其他哪些类从该实例继承 我想在C++中生成一个类,其他类继承它。但是我想确保没有人能够从这个类中创建实例,c++,C++,意思是: class Animal{ public: virtual ~Animal() {} }; class Fish: public Animal{ }; 我想确保: Fish* fish = new Fish(); 有可能,但是 Animal* ana = new Animal(); 不会 我该怎么做呢?让它成为一个让它成为一个最简单的解决方案是保护动物的构造器: Class Animal{ protected: Animal() {} public: virtu

意思是:

class Animal{
public:
virtual ~Animal() {}
};

class Fish: public Animal{
};
我想确保:

Fish* fish = new Fish();
有可能,但是

Animal* ana = new Animal();
不会


我该怎么做呢?

让它成为一个

让它成为一个

最简单的解决方案是保护动物的构造器:

Class Animal{
protected:
    Animal() {}
public:
    virtual ~Animal() {}
};

由于C++没有为抽象类提供显式支持,但是可以向类添加纯虚拟函数,以获得类似的效果。如果您没有一个合适的虚拟函数,而您希望将其设置为纯虚拟,那么一个常见的习惯用法是将析构函数设置为纯虚拟,然后在头之外提供一个实现

Class Animal{
protected:
    Animal() {}
public:
    virtual ~Animal() = 0;
};

Animal::~Animal() {
    // destructor code
}

最简单的解决方案是保护
动物的构造函数:

Class Animal{
protected:
    Animal() {}
public:
    virtual ~Animal() {}
};

由于C++没有为抽象类提供显式支持,但是可以向类添加纯虚拟函数,以获得类似的效果。如果您没有一个合适的虚拟函数,而您希望将其设置为纯虚拟,那么一个常见的习惯用法是将析构函数设置为纯虚拟,然后在头之外提供一个实现

Class Animal{
protected:
    Animal() {}
public:
    virtual ~Animal() = 0;
};

Animal::~Animal() {
    // destructor code
}

老办法是保护动物的建设者


C++11方法是将构造函数标记为已删除。

旧方法是使动物的构造函数受到保护


C++11的方法是将构造函数标记为已删除。

创建抽象类的常用习惯用法是使用纯虚拟析构函数:

struct A
{
   A();
   virtual ~A() = 0;
};
请注意,您必须为析构函数提供一个实现,即使它被标记为纯:

A::~A()
{
}

生成抽象类的常用习惯用法是使用纯虚拟析构函数:

struct A
{
   A();
   virtual ~A() = 0;
};
请注意,您必须为析构函数提供一个实现,即使它被标记为纯:

A::~A()
{
}


10.4是一个关于抽象类的完整章节,我想说它的支持是非常明确的,除非显式只是意味着有这些东西的关键字。你忘记了复制构造函数,如果你不同时保护赋值操作符
,就会出现切片问题。抽象类更好。@Plasmah所说的“显式”是指,如果不添加纯虚拟函数,就无法使类抽象——这是一种直接向编译器传达类是抽象的事实的方式,即使您不需要虚拟函数,或者根本不需要函数。@MatthieuM。我没有忘记它们——OP确实忘记了:)当然三法则仍然适用。@Plasmah:我不同意多态性需要一个
虚拟的
析构函数的观点。这是另一个问题。事实上,它只适用于
delete
on-basecase,而这种情况并不像有Java思想的人期望我们相信的那样频繁。也就是说,
virtual
析构函数的成本是如此之小,如果一个人已经有了其他的
virtual
方法,那么从一开始就添加它就更简单了。10.4是关于抽象类的一整节,我想说它的支持非常明确,除非explicit仅仅意味着要为这些内容设置关键字。您忘记了复制构造函数,如果您不同时保护赋值运算符
,则会出现切片问题。抽象类更好。@Plasmah所说的“显式”是指,如果不添加纯虚拟函数,就无法使类抽象——这是一种直接向编译器传达类是抽象的事实的方式,即使您不需要虚拟函数,或者根本不需要函数。@MatthieuM。我没有忘记它们——OP确实忘记了:)当然三法则仍然适用。@Plasmah:我不同意多态性需要一个
虚拟的
析构函数的观点。这是另一个问题。事实上,它只适用于
delete
on-basecase,而这种情况并不像有Java思想的人期望我们相信的那样频繁。也就是说,当一个人已经有了其他的
virtual
方法时,一个
virtual
析构函数的成本是如此之小,以至于从一开始就添加它就更简单了。什么是抽象类?如何使它抽象化?到这里最好的方法是什么?一行。。。都一文不值。@MatthieuM。除非你有78k的代表票,否则你的一个班轮会得到3张赞成票:)让OP决定答案是否值得。如果需要,让他问这些问题。什么是抽象类?如何使它抽象化?到这里最好的方法是什么?一行。。。都一文不值。@MatthieuM。除非你有78k的代表票,否则你的一个班轮会得到3张赞成票:)让OP决定答案是否值得。如果需要,让他问这些问题也是可能的,不要到处使用
new
where;)注:
也是可能的,不要到处使用
new
where;)在实践中,我从未见过一个类需要抽象,并且没有一些纯虚拟函数。在这种情况下,您不需要将析构函数设置为纯虚拟的(但它仍然应该是虚拟的)。@Matthieu M:这与懒惰无关。你不应该对人们的动机和想法假设太多。你真的认为所有简短的回答都意味着他们的供应商懒惰吗?这是一种可怕的偏见。你有没有停下来考虑其他的可能性?唉。@Jason:。这不是你是否懒惰的问题,只是一句俏皮话不能给出好的答案。这两个固有的缺点是,它们没有提供太多的索引(想想看谷歌),而且如果链接死了。。。他们什么也不提供。这并不意味着链接不好,它意味着它们可以作为进一步的参考,但答案应该能够独立存在。@Matthieu M:这是一个比含蓄地指责人们懒惰更好、更深思熟虑的评论。@Jason:我同意,这就是为什么讽刺性的评论w