为了账号安全,请及时绑定邮箱和手机立即绑定

派生模板-对基类成员的类访问-数据

派生模板-对基类成员的类访问-数据

C++
烙印99 2019-06-19 16:30:15
派生模板-对基类成员的类访问-数据这个问题是本文所提问题的进一步。这条线.使用以下类定义:template <class T>class Foo {public:     Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)     {         /* do something for foo */     }     T Foo_T;        // either a TypeA or a TypeB - TBD     foo_arg_t _foo_arg;};template <class T>class Bar : public Foo<T> {public:     Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)     : Foo<T>(bar_arg)   // base-class initializer     {         Foo<T>::Foo_T = T(a_arg);     }     Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)     : Foo<T>(bar_arg)     {         Foo<T>::Foo_T = T(b_arg);     }     void BarFunc ();};template <class T>void Bar<T>::BarFunc () {     std::cout << _foo_arg << std::endl;   // This doesn't work - compiler error is: error: ‘_foo_arg’ was not declared in this scope     std::cout << Bar<T>::_foo_arg << std::endl;   // This works!}在访问模板类的基类成员时,似乎必须始终使用模板样式语法对成员进行显式限定。Bar<T>::_foo_arg..有办法避免这种情况吗?“使用”语句/指令能否在模板类方法中发挥作用以简化代码?编辑:通过使用以下->语法对变量进行限定来解决范围问题。
查看完整描述

3 回答

?
米脂

TA贡献1836条经验 获得超3个赞

在Visualc+2008中工作得很好。我为您提到的类型添加了一些虚拟定义,但没有给出源代码。其余的和你说的完全一样。然后主要作用是BarFunc实例化和调用。

#include <iostream>class streamable {};std::ostream &operator<<(std::ostream &os, streamable &s) { return os; }class foo_arg_t : 
public streamable {};class a_arg_t : public streamable {};class b_arg_t : public streamable  {};template <class T>class Foo {public:
    Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)
    {
        /* do something for foo */
    }
    T Foo_T;        // either a TypeA or a TypeB - TBD
    foo_arg_t _foo_arg;};template <class T>class Bar : public Foo<T> {public:
    Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo<T>(bar_arg)   // base-class initializer
    {

        Foo<T>::Foo_T = T(a_arg);
    }

    Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo<T>(bar_arg)
    {
        Foo<T>::Foo_T = T(b_arg);
    }

    void BarFunc ();};template <class T>void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl; 
    std::cout << Bar<T>::_foo_arg << std::endl;   }int main(){
    Bar<a_arg_t> *b = new Bar<a_arg_t>(foo_arg_t(), a_arg_t());
    b->BarFunc();}


查看完整回答
反对 回复 2019-06-19
?
炎炎设计

TA贡献1808条经验 获得超4个赞

在这里,基类不是一个非依赖的基类(这意味着一个具有可以在不知道模板参数的情况下确定的完整类型的基类),并且_foo_arg是一个非依赖的名称。标准C+说,在依赖基类中不查找非依赖的名称。

若要更正代码,只需创建名称即可。_foo_arg依赖的原因是,只有在实例化时才能查找依赖的名称,并且在那个时候,必须探索的确切的基本专门化将被知道。例如:

// solution#1std::cout << this->_foo_arg << std::endl;

另一种方法是使用限定名引入依赖项:

// solution#2std::cout << Foo<T>::_foo_arg << std::endl;

必须注意此解决方案,因为如果使用不限定的非依赖名称来形成虚拟函数调用,则限定会抑制虚拟调用机制,程序的含义也会发生变化。

之后,您可以从派生类中的依赖基类中带一个名称。using:

// solution#3template <class T>class Bar : public Foo<T> {public:
    ...
    void BarFunc ();private:
    using Foo<T>::_foo_arg;};template <class T>void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl;   // works}


查看完整回答
反对 回复 2019-06-19
  • 3 回答
  • 0 关注
  • 509 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信