首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >警告:直接基类由于歧义而无法在派生中访问;这是严重的吗?

警告:直接基类由于歧义而无法在派生中访问;这是严重的吗?
EN

Stack Overflow用户
提问于 2015-05-14 19:50:15
回答 2查看 6.2K关注 0票数 1

我不明白这是什么含糊不清。我确实识别了引起歧义的那一行,并做了标记。

代码语言:javascript
复制
#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的虚拟基础,参见下图。

代码语言:javascript
复制
                  Spell
                  /   \
              v  /     \ v
                /       \
               /         \  
   SpellFromScroll      SpellWithTargets
          \                \
           \                \
            \               Sleep
             \               /
              \             / v
               \           / 
             ScrollSpell<Sleep>

在上面的图表中,为什么Sleep作为ScrollSpell<Sleep>的虚拟基础来解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-14 20:13:50

代码语言:javascript
复制
template <typename T>
class ScrollSpell : public T, public SpellFromScroll {};

在这里,T = Spell,所以ScrollSpell类将Spell类作为一个直接的、非虚拟的基类,并通过SpellFromScroll作为一个虚拟基类。这就是模棱两可。将基类T声明为虚拟类可以解决这个问题。

另外,我也不太明白设计背后的意义,所以这可能会带来一些全新的问题。

票数 5
EN

Stack Overflow用户

发布于 2015-05-14 20:11:26

为了详细说明Peter的答案,我绘制了T=Spell时得到的类图。当ScrollSpell被实例化时,编译器不知道使用哪条路径到达Scroll。但是,它也表明,使用虚拟继承并不能解决歧义。这两种方法的结果都是通向Spell的两条路径,这是不明确的。

代码语言:javascript
复制
            ╔══════╗
            ║Spell ║
            ╚══════╝ 
            /      \
╔═══════════════╗   \
║SpellFromScroll║    \
╚═══════════════╝    /
             \      /
           ╔═══════════╗  T=Spell
           ║ScrollSpell║
           ╚═══════════╝ 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30246098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档