访问自己的接口与范围运算符不起作用?

时间:2013-07-24 14:54:43

标签: c++ interface polymorphism

在玩多态性和模板时,我最终挖出了一个奇怪的(至少对我来说)范围运算符的行为。当我尝试使用* i * nterface访问* b * aseclass的方法时,使用* d *中的范围运算符* erived class,我得到一个链接器错误。我只能假设作用域操作符不会查看vtable并尝试直接从接口运行该方法,该接口实际上是纯虚拟的。

这是一个例子:

struct i
{
    virtual void set(char* in, short len) = 0;
    virtual char* getStr() = 0;
    virtual ~i() {}
};

template <int size = 10>
struct b : public i // this one is like an char-Array
{
    char str[size];
    void set(char* in, short len) { memcpy(this->getStr(),in,len); }
    char* getStr() { return str;}
};

template <int size = 10>
struct d : public  b<size> // this one is like an cString
{
    void set(char* in) { strcpy(this->getStr(),in); }
};

struct final : public d<4>
{
    void test()
    {
        set("abc"); ///< Works
        d<4>::set("abc"); ///< Works
        //set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d)
        //note: candidates are: void d<size>::set(char*) [with int size = 4]
        b<4>::set("abc",3); ///< Works
        //i::set("abc",3); ///< Linker Error:  (.gnu.linkonce.t._ZN5final4testEv+0x68) : Error : undefined reference to `i::set(char*, short)'
        //this->set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d too)
        ((i*) this)->set("abc",3); ///< Works!
    }
};

int main()
{
  final f;
  f.test();
  return 0;
}

我尝试这个的背景是,当我可能改变最终类的大小时,避免更改每次调用模板化基类的模板参数。

那么有人可以解释为什么这会在范围运算符中发生吗?

有趣的是,当将“this”指针转换为接口指针然后使用baseclass的方法时,它确实有效。这实际上是否有效且可行?

BTW:我使用的是GCC 4.1.2

编辑: 只是为了澄清,我知道d :: set是影子b :: set ..这不是问题,我只是询问链接器错误!

2 个答案:

答案 0 :(得分:0)

在类上下文中编写Base::symbol时,symbol会 始终以静态方式解析,名称查找从 班Base。原因很简单:这就是你访问的方式 派生类中的蒙面成员。否则,你将无法做到 链函数,例如:

void
Derived::function()
{
    Base::function();   //  calls the function in Base before doing anything else.
    //  ...
}

在开发C ++时,我们感觉到了这一点 重要的,即使在今天,你也想要支持某种方式 这样做。

解决这个问题的一个想法是:

template <int size=10>
struct d : public b<size>
{
    typedef b<size> Base;
    // ...
};

然后在final中,请参阅Base::set

答案 1 :(得分:0)

哦,我终于找到了自己的问题的答案:

多态性需要间接!

如上所述:Polymorphic objects on the stack?

感谢您指出这一点;)