0

在玩弄多态性和模板时,我最终发现了范围运算符的一个奇怪(至少对我而言)行为。当我尝试使用 * i * 接口和 * d *erived 类中的范围运算符访问 a * b *aseclass 的方法时,我收到链接器错误。我只能假设作用域运算符不查看 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”指针转换为接口指针然后使用基类的方法时,它确实有效。这真的有效和可行吗?

顺便说一句:我使用 GCC 4.1.2

编辑:澄清一下,我知道 d::set 正在遮蔽 b::set .. 这不是问题,我只是在询问链接器错误!

4

2 回答 2

0

当您Base::symbol在类上下文中编写时,symbol将始终静态解析,名称查找从 class 开始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

于 2013-07-24T15:01:22.897 回答
0

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

多态性需要一个间接性!

如此处所述:堆栈上的多态对象?

感谢您指出了这一点 ;)

于 2013-07-25T07:59:45.933 回答