I ran into an error yesterday and, while it's easy to get around, I wanted to make sure that I'm understanding C++ right.
昨天我遇到了一个错误,虽然很容易理解,但我想确保我对c++的理解是正确的。
I have a base class with a protected member:
我有一个受保护成员的基类:
class Base
{
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
This compiles and works just fine. Now I extend Base but still want to use b:
这将编译并正常工作。现在我扩展基数,但仍然想用b:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
Note that in this case DoSomething
is still taking a reference to a Base
, not Derived
. I would expect that I can still have access to that.b
inside of Derived
, but I get a cannot access protected member
error (MSVC 8.0 - haven't tried gcc yet).
注意,在这个例子中DoSomething仍然在引用一个基,而不是派生的。我希望我还能接触到它。b在导出内部,但我得到a无法访问受保护的成员错误(MSVC 8.0 -还没有尝试gcc)。
Obviously, adding a public getter on b
solved the problem, but I was wondering why I couldn't have access directly to b
. I though that when you use public inheritance the protected variables are still visible to the derived class.
显然,在b上添加公共getter解决了这个问题,但是我想知道为什么我不能直接访问b。
6 个解决方案
#1
36
You can only access protected members in instances of your type (or derived from your type).
You cannot access protected members of an instance of a parent or cousin type.
您只能在类型的实例(或从类型派生)中访问受保护的成员。不能访问父类或表类实例的受保护成员。
In your case, the Derived
class can only access the b
member of a Derived
instance, not of a different Base
instance.
在您的例子中,派生类只能访问派生实例的b成员,而不能访问不同的基本实例。
Changing the constructor to take a Derived
instance will also solve the problem.
更改构造函数以获取派生实例也将解决这个问题。
#2
3
You have access to the protected members of Derived
, but not those of Base
(even if the only reason it's a protected member of Derived
is because it's inherited from Base
)
您可以访问派生的受保护成员,但不能访问基础的成员(即使它是派生的受保护成员的惟一原因,因为它是从基础继承的)
#3
3
As mentioned, it's just the way the language works.
如前所述,这只是语言的工作方式。
Another solution is to exploit the inheritance and pass to the parent method:
另一个解决方案是利用继承并传递给父方法:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};
#4
1
protected
members can be accessed:
可访问受保护成员:
- through
this
pointer - 通过这个指针
- or to the same type protected members even if declared in base
- 或者对相同类型的受保护成员,即使在基地中声明
- or from friend classes, functions
- 或者来自朋友类,函数
To solve your case you can use one of last two options.
要解决您的情况,您可以使用最后两个选项之一。
Accept Derived in Derived::DoSomething or declare Derived friend
to Base:
接受派生的:::DoSomething或声明派生的朋友到Base:
class Derived;
class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
You may also consider public getters in some cases.
在某些情况下,您也可以考虑公共getter。
#5
1
class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};
//this will work
#6
-2
Use this
pointer to access protected members
使用此指针访问受保护成员
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
this->b+=that.b;
d=0;
}
};
#1
36
You can only access protected members in instances of your type (or derived from your type).
You cannot access protected members of an instance of a parent or cousin type.
您只能在类型的实例(或从类型派生)中访问受保护的成员。不能访问父类或表类实例的受保护成员。
In your case, the Derived
class can only access the b
member of a Derived
instance, not of a different Base
instance.
在您的例子中,派生类只能访问派生实例的b成员,而不能访问不同的基本实例。
Changing the constructor to take a Derived
instance will also solve the problem.
更改构造函数以获取派生实例也将解决这个问题。
#2
3
You have access to the protected members of Derived
, but not those of Base
(even if the only reason it's a protected member of Derived
is because it's inherited from Base
)
您可以访问派生的受保护成员,但不能访问基础的成员(即使它是派生的受保护成员的惟一原因,因为它是从基础继承的)
#3
3
As mentioned, it's just the way the language works.
如前所述,这只是语言的工作方式。
Another solution is to exploit the inheritance and pass to the parent method:
另一个解决方案是利用继承并传递给父方法:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};
#4
1
protected
members can be accessed:
可访问受保护成员:
- through
this
pointer - 通过这个指针
- or to the same type protected members even if declared in base
- 或者对相同类型的受保护成员,即使在基地中声明
- or from friend classes, functions
- 或者来自朋友类,函数
To solve your case you can use one of last two options.
要解决您的情况,您可以使用最后两个选项之一。
Accept Derived in Derived::DoSomething or declare Derived friend
to Base:
接受派生的:::DoSomething或声明派生的朋友到Base:
class Derived;
class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
You may also consider public getters in some cases.
在某些情况下,您也可以考虑公共getter。
#5
1
class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};
//this will work
#6
-2
Use this
pointer to access protected members
使用此指针访问受保护成员
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
this->b+=that.b;
d=0;
}
};