首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >没有实例的基类?

没有实例的基类?
EN

Stack Overflow用户
提问于 2020-01-25 09:16:11
回答 3查看 547关注 0票数 1

我肯定我不是第一个问这个问题的人,但我找不到答案。

我想要的是一个基类,从中继承多个类。继承的类都有一些函数(有实现)和一些共同的变量,并且有一些变量和函数(每个派生类的不同函数)。我想在基类中合并的普通成员。问题是,基类实际上应该只是一个基类,我不希望基类生成任何实例。我该怎么做?

如果上面的描述还不清楚的话,也许这就更清楚了:假设我想要一个基类哺乳动物和衍生类,比如人类、猿、蓝鲸等等,我想要创造人类、猿类、蓝鲸等的实例,而不是哺乳动物的例子。

我读过一些您可以将构造函数设置为私有的地方,但是我需要派生类的公共构造函数。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-25 09:37:29

因为每个方法都是在基类中实现的,所以使用受保护的构造函数将允许您在派生类中添加额外的成员变量,而不需要构造基类。更明显的是,我可能会将基类放在不同的名称空间中,这样调用者就会得到一个强烈的提示,表明他们甚至不应该尝试创建一个。

代码语言:javascript
运行
复制
namespace detail
{

class Mammal
{
public:
    void layEggs() { /*implementation*/ }

protected:
    //Stop anyone creating a Mammal
    //Can still be accessed by derived classes,
    //and anyone that Mammal has declared a friend
    Mammal(int age) : age_(age);

    int age_;
};
}

class Dog : public detail::Mammal
{
public:
    //Dog is still allowed to access Mammal constructor
    Dog(int age, const std::string& name) : 
        Mammal(age), name_(name) 
    {} 

protected:
    std::string name_;
};

编辑:我最初回答时没有理解每个方法都是在基类中实现的。

您可以通过使类成为抽象类来做到这一点。要做到这一点,至少要创建一个函数纯虚函数

代码语言:javascript
运行
复制
class Mammal
{
public:
    void layEggs()
    {
        //implemented in base
    }

    virtual std:string speak() = 0 //pure virtual, so class cannot be instantiated
};

class Dog : public Mammal
{
public:
    virtual std::string speak()
    {
        return "woof";
    }
};

因为哺乳动物包含一个pure virtual函数,所以不能从它创建变量。然而,Dog已经实现了所有的函数,因此可以创建一个变量。

代码语言:javascript
运行
复制
Mammal m; //will result in compiler error, because what would m.speak() do?
Dog d; //is allowed, because we know what d.speak() should do
票数 2
EN

Stack Overflow用户

发布于 2020-01-25 09:35:42

使基类抽象是您的解决方案。

如果不想使任何基类方法为纯虚拟,则可以将析构函数变为纯虚拟的。

代码语言:javascript
运行
复制
#include <iostream>
using namespace std;

class IMammal //I for Interface
{
    public:
        virtual ~IMammal() = 0; //Makes the class abstract, Pure virtual destructor
};

IMammal::~IMammal() //Its necessary or ld will complain
{
    cout << "In ~IMammal" << endl;
}

class Ape : IMammal
{

};

int main()
{
//    IMammal m; // error: cannot declare variable ‘m’ to be of abstract type ‘IMammal’
    Ape a;
}
票数 3
EN

Stack Overflow用户

发布于 2020-01-25 09:28:02

我认为艾伦·伯特尔斯的建议可能确实有效。检查这个问题受保护构造函数的实际用途是什么?

基类中的所有函数都有基类中的实现。否则,使用虚拟函数也是一种选择。我查看了这个网站https://www.geeksforgeeks.org/pure-virtual-functions-and-abstract-classes/,也许这对其他人是有用的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59907891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档