c++ - 在派生类中使用来自虚拟基类的 protected 构造函数

标签 c++ virtual derived

我有一个针对某些音频格式的抽象伪基类,有 2 个成员 - 一个适用于派生类,但另一个给了我一个我无法解决的错误。 它说我无法访问 MP3 中声明的 protected 成员,但为什么它可以到达一个 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;
}

最佳答案

两个原因:

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

    the using-declaration does not by itself suppress the implicit declaration of the derived class member

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

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

    A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.

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

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

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

关于c++ - 在派生类中使用来自虚拟基类的 protected 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47618632/

相关文章:

c++ - 类型在编译时已知的虚拟方法

c++ - 在 C++ 可执行文件中枚举派生类

c++ - 如何初始化一个静态成员

c++ - Box2D 旋转中心

c++ - 使用 `__DATE__` 或 `__TIME__` 是否违反单一定义规则?

c++ - 现代 OpenGL : VBO, GLM 和矩阵堆栈

c++ - 具有固定实现的虚函数不使用 (*this) 的大多数派生类

c++ - 在模板中使用非虚拟分派(dispatch)

hql - 在 Hibernate HQL 中使用派生表进行子查询

ruby - 在 Ruby 中调用 super 方法