2011-09-08 134 views
0

我正在使用code :: blocks,我认为gcc。给出的示例代码(这是伪代码,并可能无法复制的问题):C++继承问题

//Assume this is in a separate header file to B 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

class TestB : public TestA 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 

我会得到类似的编译错误,如: 错误:“A”不在此范围内声明。 错误:Function1()未在此范围内声明。

我的印象是所有的基本变量和函数都继承了子类。鉴于基类有很多函数和变量,我不想使用'using'关键字,因为我必须为每个函数和变量声明它(据我所知)。

有什么办法让TestB明确或实际包含它继承的东西吗?

有关片段如下

好。这是不可能的,包括示例代码,因为它是在项目,但我将引用关键片段:

C:\Users\user\Desktop\Projects\RND2\TemplateListAdv.h|30|error: 'Size' was not declared in this scope| 

线,这是对是:

if(!Array.SetToSize(Size)) 

类它在为:

template<typename TemplateItem> 
class TemplateListAdv : public TemplateList<TemplateItem> 

而且从TemplateList牵连行是:

SIZE_TYPE Size; //SIZE_TYPE is unsigned long. 
//SIZE_TYPE is available in all files as unsigned long. 

文件去: TemplateList.h-> TemplateBasics.h-> TemplateListAdv.h

从我所能看到的没有丢失的文件。

我会解决它,'使用'关键字可以单独解决它,但这一直在扰乱我,因为我认为继承是自动的。

编译器数据的要求:

“释10.05转6283(2010-05-27 9时09分13秒),GCC 4.4.1的Windows/Unicode的 - 32位”

+1

这应该像预期的那样工作,所以你必须找到一个例子,它会失败... – carlpett

+2

尝试张贴真实的代码和他们所在的文件。据我可以告诉它只是看起来像你不'在testb.cpp中包含#include“testa.h” – sashang

+1

发布出现错误的代码,此代码没有错误。 –

回答

1

的问题,你”重新访问类模板访问基类的东西,是FAQ item

而不是在这里引用整个FAQ项目,我只是链接到它:这是你的答案。

您提供的用于说明问题的代码无关,对不起。给出一个实际的例子,而不是一个人认为可能是问题的例子,总是一个好主意。

干杯&心连心,

+0

谢谢。我会读到它。 – SSight3

+0

是否有我可以使用的通用'使用'调用? – SSight3

+0

@ SSight3:你可以通过用'this'前缀来将*非依赖*表达式'Size'转换成*依赖*:this-> Size'告诉编译器表达式是*依赖*模板参数,然后(* magic发生*:lookup被推迟到实例化,其中基础也被实例化),它将解决问题。 –

1

的问题是,你正在使用的模板,和基类是“从属名称”。也就是说,模板基类可能是专用的,并且没有Size成员,因为Size引用不在依赖上下文中,所以编译器不知道它何时编译您的类。

在您的特定情况下,最简单的方法是使用this来指代继承的成员:

if(!Array.SetToSize(this->Size)) 

而且由于this是一个从属名称,它应该工作

1

你肯定:

  • 大小是TemplateList的保护或公共属性?

  • 你不是从静态方法调用if(!Array.SetToSize(Size))?

1

这个问题真的很糟糕,你可能想改进一下。无论如何,我的水晶球告诉我,Size定义在基本模板中,并且因为标识符Size不是,因此查找不会进入基本模板,编译器也不会看到它。在Size之前添加this->,您应该设置。

+0

改进建议? – SSight3

+0

如果有关于如何改进问题的建议:模板在语言中是非常具体的问题,那么问题最初包含模板的任何问题应该从那里开始,在某些情况下它不会相关,但在其他情况下它将会是相关的。不要提供不复制问题的代码示例,尝试在较小的测试用例中复制环境中的相同错误,它可以帮助您了解问题以及它的哪些部分是相关的(在这种情况下,它会有告诉你,删除模板消除了问题:模板很重要) –

1

当解释模板成员函数时,编译器必须(遵循标准)为每个符号决定它是否依赖于模板参数。如果它依赖于它,那么只有在实例化模板时才会解析它。但是,他现在必须解决它。

就你而言,编译器认为AFunction1不依赖于模板参数,因此应该在解析后立即解析。你只需要使它取决于使用的模板参数this->Athis->Function1

所以,你应该有这样的东西。

template < typename T > 
class Base 
{ 
protected: 
    int A; 

public: 
    void Function1() { A = 0; } 
}; 

template < typename T > 
class Derived : public Base<T> 
{ 
public: 
    void CallFunction1() { 
    this->A = 10; 
    this->Function1(); 
    } 
}; 
2

因此,它看起来像你是错误的模板类继承,是不是?与非模板相比,它们有很大的不同。假设你有这样的代码:

 

template <class T> 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 
 

的问题是由两阶段名称查找引起的。基种皮类的所有成员都依赖名字,即它们依赖于模板参数T.这是因为你可以有模板专业化的种皮有完全不同的成员,如:

 

template <class T> 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 

template <> 
class TestA<int> 
{ 
}; 
 

现在,在TestA中不是A和Function1成员,所以它们在TestB中也是不可访问的。为了让编译器知道这些成员确实depende的模板参数,你应该写TESTB这样的:

 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ this->A = 10; this->Function1();}// 
}; 
 

这样,你让编译器解析名称仅在模板实例的时间,而不是模板声明时,它会以基类成员而闻名。

有一点需要补充的是,VC编译器没有这样的问题,它不尝试解析模板直到实例化,因此不支持两阶段名称查找。