如果下面的类不是模板,我可以简单地x在derived课堂上.但是,使用下面的代码,我必须使用this->x.为什么?
template <typename T>
class base {
protected:
int x;
};
template <typename T>
class derived : public base<T> {
public:
int f() { return this->x; }
};
int main() {
derived<int> d;
d.f();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 当我调查Qt的源代码时,我发现trolltech的人明确使用this关键字来访问析构函数中的字段.
inline ~QScopedPointer()
{
T *oldD = this->d;
Cleanup::cleanup(oldD);
this->d = 0;
}
Run Code Online (Sandbox Code Playgroud)
那么,这个用法有什么意义呢?有什么好处吗?
编辑:对于那些投票支持关闭此问题的人,我怀疑这种用法适用于某些类继承案例
QScopedPointer类定义的一部分:
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
Run Code Online (Sandbox Code Playgroud) 上下文:
受保护和公共类成员的继承是面向对象编程的基本概念.下面的简单示例说明了一个经常遇到的情况,其中类CDerived继承了类的所有公共成员,CBase并添加了自己的1个附加函数,而不更改或显式重新定义或重新定义类的任何公共成员CBase.
#include <stdio.h>
class CBase
{
public:
char Arr[32];
int Fn1(void) {
return Arr[1] ^ Arr[sizeof(Arr)-1];
}
int Fn2(void) {
return Arr[2] ^ Arr[sizeof(Arr)-2];
}
};
class CDerived : public CBase
{
public:
int FnSum(void) {
return Fn1() + Fn2();
}
};
int main(void)
{
CDerived ddd;
printf("%d\n", ddd.Fn1());
printf("%d\n", ddd.Fn2());
printf("%d\n", ddd.FnSum());
return (int)ddd.Arr[0];
};
Run Code Online (Sandbox Code Playgroud)
上面的代码在所有主要编译器上编译都没有问题.
但是,如果希望" 模板化 "此代码,例如:通过参数化Arr数组的大小,那么CBase类模板的所有公共成员对CDerived符合最新C++标准的编译器上的类模板都是不可见的.
以下是问题代码:
#include <stdio.h>
template …Run Code Online (Sandbox Code Playgroud) 我在这里有一个旧的代码库,他们使用受保护的成员变量.可以讨论这是否是一个好主意.但是,代码必须与gcc3编译良好.我有一个派生模板类Bar,它使用类模板Foo中的受保护成员x
template <class Something> class Foo {
public:
// stuff...
protected:
some::type x;
}
template <class Something> Bar : Foo<Something> {
public:
void cleanup();
}
Run Code Online (Sandbox Code Playgroud)
在cleanup()的方法声明中,有一些用x完成的事情
template <class Something> void Bar<Something>::cleanup() {
doSomeThingCleanUpLike (x);
}
Run Code Online (Sandbox Code Playgroud)
这不适用于gcc4,虽然它应该与gcc3一起使用.当我将其更改为时,它可以工作
doSomeThingCleanUpLike (this->x);
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
可能的重复:
GCC问题:使用依赖于模板参数的基类成员
为什么当VS没有时,GCC在模板中需要额外的声明?
为什么派生模板类不能访问基本模板类
iphone编译器继承模板化基类,传递类型未及时扩展(只看)
抱歉这个令人困惑的标题,我能想出最好的.
这里有一些代码来说明我的问题......
基本模板类:
template<class T> class TestBase
{
public:
int someInt;
};
Run Code Online (Sandbox Code Playgroud)
试图用另一个模板类继承TestBase ...
这在编译时得到"someInt未在此范围内声明":
template<class X> class TestSub : public TestBase<X>
{
void testf()
{
someInt = 0; //Error: "someInt was not declared in this scope"
}
};
Run Code Online (Sandbox Code Playgroud)
B)这很好用(不同之处在于我明确指定了TestBase的模板输入)
template<class X> class TestSub : public TestBase<string>
{
void testf()
{
someInt = 0;
}
};
Run Code Online (Sandbox Code Playgroud)
为什么(A)的TestSub没有像(B)中那样正确地继承someInt?
提前致谢.
可能重复:
GCC问题:使用依赖于模板参数的基类成员
我以为我熟悉C++,但显然不够熟悉.
问题是当您在模板类中定义常量时,可以在从该类派生的新类中使用常量,但不能从派生自它的新模板类中使用常量.
例如,gcc说
test.h:18:错误:未在此范围内声明'theconstant'
当我尝试编译这个(简化的)头文件时:
#pragma once
template <typename T> class base
{
public:
static const int theconstant = 42;
};
class derive1 : public base<size_t>
{
public:
derive1(int arg = theconstant) {}
};
template<typename T> class derive2 : public base<T>
{
public:
derive2(int arg = theconstant) {} // this is line 18
};
Run Code Online (Sandbox Code Playgroud)
所以问题是一个类derive1编译得很好,但是另一个类derive2,它是模板特化,却没有.
现在也许gcc的错误还不够清楚,但是我不明白为什么构造函数的derive2范围不同于derive1.
如果它很重要,这会在编译头文件本身时发生,而不是在实例化类型的对象时derive2<type>.
我也知道要改进什么来进行编译,所以我并不是真的在寻找单行代码作为答案.我想知道为什么会这样!我尝试在网上搜索,但显然我没有使用正确的搜索参数.
我试图在派生类中使用模板化基类的成员变量,如下例所示:
template <class dtype>
struct A {
int x;
};
template <class dtype>
struct B : public A<dtype> {
void test() {
int id1 = this->x; // always works
int id2 = A<dtype>::x; // always works
int id3 = B::x; // always works
int id4 = x; // fails in gcc & clang, works in icc and xlc
}
};
Run Code Online (Sandbox Code Playgroud)
gcc和clang都非常挑剔使用这个变量,并且要求显式范围或明确使用"this".使用其他一些编译器(xlc和icc),事情就像我期望的那样工作.这是xlc和icc的情况,允许代码不是标准的,还是gcc和clang中的错误?
编辑:这不是一个错误,只是我不知道模板化基类中的依赖名称查找(MSVC"有帮助"解决没有错误).
我前段时间写了一个functor实现,还有一个使用它的简单"Event"包装器.它在MSVC下编译得很好,但GCC给出了基类中成员变量的错误subscribers,没有被声明; 改变subscribers以this->subscribers解决问题(!).它似乎只发生在奇怪的重复模板模式和部分模板专业化.
简化的来源(对于令人费解的模板使用感到抱歉......):
#include <vector>
template<typename TEvent>
struct EventBase
{
protected:
std::vector<int> subscribers;
};
template<typename TArg1 = void, typename TArg2 = void>
struct Event : public EventBase<Event<TArg1, TArg2> >
{
void trigger(TArg1 arg1, TArg2 arg2) const
{
// Error on next line
auto it = subscribers.cbegin();
}
};
template<typename TArg1>
struct Event<TArg1, void> : public EventBase<Event<TArg1> >
{
void trigger(TArg1 arg1) const
{
// Using `this` fixes error(?!)
auto it = …Run Code Online (Sandbox Code Playgroud) 在visual C++中,我可以做这样的事情:
template <class T>
class A{
protected:
T i;
};
template <class T>
class B : public A<T>{
T geti() {return i;}
};
Run Code Online (Sandbox Code Playgroud)
如果我尝试用g ++编译它,我会收到一个错误.我必须这样做:
template <class T>
class B : public A<T>{
T geti() {return A<T>::i;}
};
Run Code Online (Sandbox Code Playgroud)
我不应该在标准C++中做前者吗?或者是gcc错误配置给我错误的东西?
c++ ×9
templates ×7
inheritance ×4
gcc ×3
g++ ×2
name-lookup ×2
this ×2
visual-c++ ×2
c++-faq ×1
protected ×1
qt ×1