在派生类中使用来自虚拟基类的受保护 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的主要内容,如果未能解决你的问题,请参考以下文章