在派生类中使用来自虚拟基类的受保护 ctor

Posted

技术标签:

【中文标题】在派生类中使用来自虚拟基类的受保护 ctor【英文标题】:use protected ctor from virtual base class in derived class 【发布时间】:2017-12-03 13:01:12 【问题描述】:

我有一个带有 2 个 ctor 的某些音频格式的抽象伪基类 - 一个适用于派生类,但另一个给我一个我无法解决的错误。 它说我无法访问 MP3 中声明的受保护成员,但为什么它可以到达一个 ctor 而不是另一个?

class Audioformat

protected:
    string song="";
    Audioformat(string s) :song(s) ;//This ctor gives me the error
    Audioformat()  song = "unknown";
public:
    virtual void play()=0;
    virtual void info() = 0;
    virtual ~Audioformat() = 0 ;
;
class MP3 : public Audioformat

public:
    using Audioformat::Audioformat;
    void play()  cout << "pseudo-play" << endl; 
    void info()  cout << song << endl; 
    ~MP3()  cout << "MP3" << endl; delete this; 
;

这是我的主要内容:

int main()


    MP3 song1;//WORKS
    MP3 song2 "random trash song" ;//ERROR    MP3::MP3(std::string) is inaccessible
    play(song1);
    info(song1);
    getchar();
    return 0;

【问题讨论】:

OT:delete this; 什么? delete this 仅在您确保 MP3 的所有实例都是使用 new 创建时才有效(例如,通过将构造函数设为私有并添加 static 创建函数)。即便如此,它也不应该被称为 from 析构函数,因为这显然会产生无限递归。然而,对于一个名为MP3 的类,我无法想象一个合理的用例。这对于事件管理系统来说更为典型。 哦,string song=""; 是不必要的。这不是 Java。让它std::string song;. hm 我的老师告诉我,我必须在每个析构函数中删除这个(指向对象的指针)以避免内存泄漏(或者我可能有点错误) - 我对 c++ 有点陌生所以感谢您指出了这一点。我没有发布它,但我使用命名空间 std;在文件的开头 @BMAY - 很抱歉告诉你,但你的老师正在向你传授书中所有不好的做法。 【参考方案1】:

两个原因:

    单独使用声明不会抑制特殊类成员的隐式声明。在这种情况下,默认 c'tor ([namespace.udecl]/4):

    using 声明本身并不抑制隐式 派生类成员的声明

    因此,MP3 的公共默认 c'tor 由编译器合成,并在您的示例中调用。

    using 声明引入的 c'tors 基本上具有与基类 ([namespace.udecl]/19) 中相同的可访问性:

    命名构造函数的 using-declarator 不创建同义词;相反,额外的构造函数是 可访问的,如果它们在用于构造时可以访问 相应基类的对象,以及 using-declaration 被忽略。

    因此在main 中无法访问获取字符串的c'tor,因为它也在MP3 中受到保护。

如果您想在MP3 中有一个接受std::string 的公共c'tor,您必须完整定义它,并明确转发到基类c'tor:

public:
  MP3(std::string s) : Audioformat(s) 

【讨论】:

所以我必须做类似这样的 MP3(string s):song(s) 但歌曲不是非静态的,所以这不起作用。 @BMAY - 我写的正是你必须做的。您不必猜测和弄错。 抱歉 - 我的网站没有正确重新加载 - 非常感谢

以上是关于在派生类中使用来自虚拟基类的受保护 ctor的主要内容,如果未能解决你的问题,请参考以下文章

从派生类访问基类中的受保护成员

派生类无法访问基类的受保护方法

C++ 派生模板类:访问实例的受保护成员

访问派生类中的受保护成员

为什么派生类d的对象不能调用基类的受保护成员函数?

protected 成员与派生类