C++ 虚拟继承和访问 public 虚拟方法,其实现在继承受保护的 class 中
C++ virtual inheritance and access to a public virtual method whose implementation is in a class whose inheritance is protected
我正在使用虚拟继承来创建一个 class EditablePrimeNumberSet(一组素数),它继承了 class EditableNumberSet(一组可以递增的整数),同时仅公开base class NumberSet(一组数字)。
(我不希望我的 class 暴露方法 add 会导致一个不只包含质数的集合)
备注:这只是一个简单的例子。我实际上不研究素数。这个例子只是为了说明我面临的问题。
我的问题是,当我想在 EditableNumberSet 变量上调用虚方法 contains44 时,我需要 static_cast 它以避免编译错误。看起来编译器发现直接实现是易于处理的,因为它知道我的对象的实际类型,但随后发现此方法不可访问。所以,实际上,我并没有被卡住,但觉得这样做很好奇而且不优雅 static_cast。是否有一些改进我的代码的技巧?
using namespace std;
class NumberSet {
public :
int size() {return myList.size();}
virtual bool contains44()
{
cout << "in base method\n";
return myList.count(44)>0;
};
protected :
set<int> myList;
};
class EditableNumberSet : public virtual NumberSet {
public :
void add(int i) {myList.insert(i);}
bool contains44() override
{
cout << "in inherited method\n";
return false;
} // 44 is not a prime number
};
class EditablePrimeNumberSet: public virtual NumberSet, protected EditableNumberSet {
public :
void addNearestPrimeNumber(int i)
{
int j=0;
//code that set j to the nearest prime number next to i...
add(j);
}
};
int main()
{
EditablePrimeNumberSet listPN;
listPN.addNearestPrimeNumber(45);
listPN.NumberSet::contains44(); // use base class method implementation
static_cast<NumberSet &>(listPN).contains44(); // use derived class method implementation
listPN.contains44(); // error: ‘virtual bool EditableNumberSet::contains44()’ is inaccessible within this context
}
如果您想从受保护的 class 中公开单个名称,您可以使用 using
声明:
class EditablePrimeNumberSet : public virtual NumberSet, protected EditableNumberSet {
public:
using EditableNumberSet::contains44; // Expose EditableNumberSet::contains44 as
// part of EditablePrimeNumberSet's public interface
void addNearestPrimeNumber(int i)
{
int j = 0;
//code that set j to the nearest prime number next to i...
add(j);
}
};
然后当您调用 listPN.contains44()
时,您调用继承的方法。
我正在使用虚拟继承来创建一个 class EditablePrimeNumberSet(一组素数),它继承了 class EditableNumberSet(一组可以递增的整数),同时仅公开base class NumberSet(一组数字)。 (我不希望我的 class 暴露方法 add 会导致一个不只包含质数的集合)
备注:这只是一个简单的例子。我实际上不研究素数。这个例子只是为了说明我面临的问题。
我的问题是,当我想在 EditableNumberSet 变量上调用虚方法 contains44 时,我需要 static_cast 它以避免编译错误。看起来编译器发现直接实现是易于处理的,因为它知道我的对象的实际类型,但随后发现此方法不可访问。所以,实际上,我并没有被卡住,但觉得这样做很好奇而且不优雅 static_cast。是否有一些改进我的代码的技巧?
using namespace std;
class NumberSet {
public :
int size() {return myList.size();}
virtual bool contains44()
{
cout << "in base method\n";
return myList.count(44)>0;
};
protected :
set<int> myList;
};
class EditableNumberSet : public virtual NumberSet {
public :
void add(int i) {myList.insert(i);}
bool contains44() override
{
cout << "in inherited method\n";
return false;
} // 44 is not a prime number
};
class EditablePrimeNumberSet: public virtual NumberSet, protected EditableNumberSet {
public :
void addNearestPrimeNumber(int i)
{
int j=0;
//code that set j to the nearest prime number next to i...
add(j);
}
};
int main()
{
EditablePrimeNumberSet listPN;
listPN.addNearestPrimeNumber(45);
listPN.NumberSet::contains44(); // use base class method implementation
static_cast<NumberSet &>(listPN).contains44(); // use derived class method implementation
listPN.contains44(); // error: ‘virtual bool EditableNumberSet::contains44()’ is inaccessible within this context
}
如果您想从受保护的 class 中公开单个名称,您可以使用 using
声明:
class EditablePrimeNumberSet : public virtual NumberSet, protected EditableNumberSet {
public:
using EditableNumberSet::contains44; // Expose EditableNumberSet::contains44 as
// part of EditablePrimeNumberSet's public interface
void addNearestPrimeNumber(int i)
{
int j = 0;
//code that set j to the nearest prime number next to i...
add(j);
}
};
然后当您调用 listPN.contains44()
时,您调用继承的方法。