看起来无法通过shared_ptr访问受保护的成员。这是一个没有编译的最小例子:
// compile with g++ -std=c++11 protect.cpp
#include <iostream>
#include <memory>
class C
{
public:
C(int xval = 0) : x(xval) {}
protected:
int x = 0;
};
class D : public C
{
public:
D(int xval = 0) : C(xval) {}
void print_sum( const std::shared_ptr<C>& other );
};
void D::print_sum( const std::shared_ptr<C>& other )
{
int sum = x + other->x;
std::cout << "the sum is " << sum << std::endl;
}
int main( int argc, char** argv, char** envp)
{
std::shared_ptr<C> first = std::make_shared<C>(2);
std::shared_ptr<D> second = std::make_shared<D>(3);
second->print_sum( first );
return 0;
}
以下是我收到的具体错误消息:
$ g++ -std=c++11 protect.cpp
protect.cpp: In member function ‘void D::print_sum(const std::shared_ptr<C>&)’:
protect.cpp:13:15: error: ‘int C::x’ is protected
int x = 0;
^
protect.cpp:25:25: error: within this context
int sum = x + other->x;
尽管D
来自x
,但D
无法访问C
,这似乎很奇怪,我一直认为派生类可以使用protected
基类成员。
这个问题对我来说并不是一个真正的阻碍;在我的用例中,C
和D
将作为同一补丁集的一部分实现,因此只需将x
公开作为解决方法即可。但是,是否有更多的惯用语&#34;使这段代码有效的方法?
以防这是一个gcc错误,以下是我使用的版本:
$ cat /etc/issue
Ubuntu 14.04.3 LTS \n \l
$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
答案 0 :(得分:2)
引用此SO answer:
您只能在您的类型的实例中访问受保护的成员(或 从你的类型派生而来)。您无法访问受保护的成员 父母或堂兄类型的实例。
这意味着您可以从D访问this->x
或d.x
(其中d
是D
类型的另一个对象),而不是c.x
即使c
是C
类型的对象。
修复是将D声明为C:
的朋友class D; // forward declare D
class C
{
public:
C(int xval = 0) : x(xval) {}
friend class D; // <--
protected:
int x = 0;
};
或将参数设为C,而不是D:
// no need for any friend declaration for this
void print_sum( const std::shared_ptr<D>& other );
顺便说一句,这与共享指针无关。