警告:由于歧义而导致的直接基类无法访问;这是严重的
Warning: direct base class inaccessible in derived due to ambiguity; is this serious?
我不明白这里的歧义是什么。我确实确定了引起歧义并标记的线。
#include <string>
#include <unordered_map>
class Spell {
protected:
struct Exemplar {};
Spell() = default;
Spell (Exemplar, const std::string&);
};
class SpellFromScroll : virtual public Spell {
private:
static std::unordered_map<std::string, SpellFromScroll*> prototypesMap;
public:
static void insertInPrototypesMap (const std::string& tag, SpellFromScroll* spell) {
prototypesMap.emplace (tag, spell);
}
template <typename T> static SpellFromScroll* createFromSpell (T*);
};
std::unordered_map<std::string, SpellFromScroll*> SpellFromScroll::prototypesMap;
class SpellWithTargets : virtual public Spell {}; // *** Note: virtual
class Sleep : public SpellWithTargets {
private:
static const Sleep prototype;
public:
static std::string spellName() {return "Sleep";}
private:
Sleep (Exemplar e) : Spell (e, spellName()) {}
};
const Sleep Sleep::prototype (Exemplar{});
template <typename T>
class ScrollSpell : /*virtual*/ public T, public SpellFromScroll {};
Spell::Spell (Exemplar, const std::string& spellName) {
// Ambiguity warning!
SpellFromScroll::insertInPrototypesMap (spellName, SpellFromScroll::createFromSpell(this));
}
template <typename T>
SpellFromScroll* SpellFromScroll::createFromSpell (T*) {
return new ScrollSpell<T>;
}
int main() {}
/*
c:ADandD>g++ -std=c++14 Ambiguity.cpp -o a.exe -Wall -Wextra -pedantic-errors
Ambiguity.cpp: In instantiation of 'class ScrollSpell<Spell>':
Ambiguity.cpp:32:13: required from 'static SpellFromScroll* SpellFromScroll::createFromSpell(T*) [with T = Spell]'
Ambiguity.cpp:27:90: required from here
Ambiguity.cpp:23:7: warning: direct base 'Spell' inaccessible in 'ScrollSpell<Spell>' due to ambiguity
class ScrollSpell : public T, public SpellFromScroll {};
^
Ambiguity.cpp:23:7: warning: virtual base 'Spell' inaccessible in 'ScrollSpell<Spell>' due to ambiguity [-Wextra]
c:ADandD>
*/
这有多严重,随着程序的发展,以后会出问题?
更新:通过让t成为ScrollSpell<T>
的虚拟基础找到解决方案。但是在我的程序中,t始终是派生类别的类别,咒语始终是T的虚拟基础。请参见下面的图。
Spell
/
v / v
/
/
SpellFromScroll SpellWithTargets
Sleep
/
/ v
/
ScrollSpell<Sleep>
在上图中,为什么Sleep
是ScrollSpell<Sleep>
的虚拟基础解决问题?
template <typename T>
class ScrollSpell : public T, public SpellFromScroll {};
在这里,T = Spell
,因此ScrollSpell
类将Spell
类是直接的非虚拟基类,也是通过SpellFromScroll
的虚拟基类。那就是歧义。将基类T
声明为虚拟可能解决问题。
我也不太了解设计背后的观点,因此可能会引入一些全新的问题。
要详细说明彼得·B的答案,我绘制了当t = spell时产生的类图。编译器不知道在实例化卷轴时要滚动的路径。但是,这也表明,使用虚拟继承并不能解决歧义。两种方法结果都是Spell
的两条路径,这是模棱两可的。
╔══════╗
║Spell ║
╚══════╝
/
╔═══════════════╗
║SpellFromScroll║
╚═══════════════╝ /
/
╔═══════════╗ T=Spell
║ScrollSpell║
╚═══════════╝
相关文章:
- 为什么此派生对象无法访问基类的后递减方法?
- 继承和友元函数,从基类访问受保护的成员
- 无法访问基类函数 C++
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 如何从派生类中的基类访问变量的值?
- 抽象类的需求是什么?为什么要通过其基类访问派生类方法?在C++
- 如何从另一个类的基类访问派生类中的受保护成员
- 尝试从基类访问受保护的构造函数时出现错误 C2248
- 从C++中的基类访问子数据
- 从抽象基类访问另一个基类成员
- 从Derivered类设置值,同时从基类访问相同的值
- 如何使用多态性从基类访问派生类向量成员
- 如何在C++中从基类访问派生类的属性
- 从基类访问联合的公共部分
- (c++)从私有基类访问私有成员变量
- 类的某些成员只能由基类访问吗
- 无法从c++基类访问变量
- C++从基类访问两个类组成中的私有成员
- 基类访问规范与类成员访问规范
- 从基类访问派生类