假设给出了以下类:
class Base{
public:
Base() {}
Base( const Base& b) : base_attr(b.base_attr) {}
void someBaseFunction()
{ .... }
protected:
SomeType base_attr;
};
当我希望一个类继承自该类并为派生类包含一个新属性时,我会这样写:
class Derived: public Base {
public:
Derived() {}
Derived( const Derived& d ) : derived_attr(d.derived_attr)
{
this->base_attr = d.base_attr;
}
void SomeDerivedFunction()
{ .... }
private:
SomeOtherType derived_attr;
};
这对我有用(让我们忽略最终丢失的分号等)。
但是,当我在派生类的复制构造函数中删除“this->”时,编译器会提示“‘base_attr’未在此范围内声明”。
我认为,当从一个类继承时, protected 属性也可以直接访问。我不知道需要“this->”指针。 我现在很困惑我在那里所做的是否真的正确,尤其是派生类的复制构造函数。
因为每个 Derived 对象都应该有一个 base_attr 和一个 derived_attr 并且它们显然需要正确初始化/设置。 因为 Derived 是从 Base 继承的,所以我不想在 Derived 类中明确包含一个名为“base_attr”的属性。恕我直言,这样做通常会破坏继承背后的想法,因为一切都必须重新定义。
编辑
谢谢大家的快速回答。我完全忘记了类实际上是模板这一事实。
请查看下面的新示例,这些示例在派生类的复制构造函数中包含“this->”时实际上正在编译,而在省略“this->”时失败: 基类:
#include <iostream>
template<class T>
class Base{
public:
Base() : base_attr(0) {}
Base( const Base& b) : base_attr(b.base_attr) {}
void baseIncrement()
{ ++base_attr; }
void printAttr()
{
std::cout << "Base Attribute: " << base_attr << std::endl;
}
protected:
T base_attr;
};
派生类:
#include "base.hpp"
template< class T >
class Derived: public Base<T>{
public:
Derived() : derived_attr(1) {}
Derived( const Derived& d) : derived_attr(d.derived_attr) {
this->base_attr = d.base_attr;
}
void derivedIncrement()
{ ++derived_attr; }
protected:
T derived_attr;
};
为了完整起见,还有主要功能:
#include "derived.hpp"
int main()
{
Derived<int> d;
d.printAttr();
d.baseIncrement();
d.printAttr();
Derived<int> d2(d);
d2.printAttr();
return 0;
};
我正在使用 g++-4.3.4。 虽然我现在明白这似乎来 self 使用模板类定义的事实,但我不太明白使用模板时导致问题的原因以及为什么不使用模板时它会起作用。有人可以进一步澄清这一点吗?
最佳答案
只有在 Base
时你才会看到这个在某种程度上取决于模板参数。
在那种情况下,像base_attr
这样的名字被认为太危险了。在这样的依赖基类中查找:对于某些模板实例化,可以在基类中找到名称,而对于另一个实例化,成员可能不存在,名称将引用某个命名空间成员。
因为这被认为是令人困惑的,C++ 遵循一致的规则 base_attr
进行非限定名称查找时从不在依赖基类中查找。您需要在名称前加上 this->
或类名,如 Derived<T>::base_attr
.所以当基类没有声明 base_attr
时,该名称不会默默地引用可能全局声明的名称,但它只是一个编译时错误。
关于c++ - 为什么需要 this 指针来访问继承的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4510672/