在派生 class 中使用来自虚拟基础 class 的受保护构造函数
use protected ctor from virtual base class in derived class
我有一个抽象的伪基础 class 用于某些具有 2 个 ctors 的音频格式 - 一个适用于派生 class 但另一个给了我一个我无法解决的错误。
它说我无法访问在 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;
}
两个原因:
单独使用声明不会抑制特殊 class 成员的隐式声明。在这种情况下,默认 c'tor ([namespace.udecl]/4):
the using-declaration does not by itself suppress the implicit
declaration of the derived class member
因此 MP3
的 public 默认 c'tor 由编译器合成,并在您的示例中调用。
由 using 声明引入的 c'tors 基本上具有与基本相同的可访问性 class ([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,你必须完整定义它,并转发到基础 class c'tor明确:
public:
MP3(std::string s) : Audioformat(s) {}
我有一个抽象的伪基础 class 用于某些具有 2 个 ctors 的音频格式 - 一个适用于派生 class 但另一个给了我一个我无法解决的错误。 它说我无法访问在 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;
}
两个原因:
单独使用声明不会抑制特殊 class 成员的隐式声明。在这种情况下,默认 c'tor ([namespace.udecl]/4):
the using-declaration does not by itself suppress the implicit declaration of the derived class member
因此
MP3
的 public 默认 c'tor 由编译器合成,并在您的示例中调用。由 using 声明引入的 c'tors 基本上具有与基本相同的可访问性 class ([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,你必须完整定义它,并转发到基础 class c'tor明确:
public:
MP3(std::string s) : Audioformat(s) {}