C ++ 11似乎无法通过shared_ptr访问受保护的成员

时间:2015-11-03 17:49:40

标签: c++ oop c++11 inheritance shared-ptr

看起来无法通过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基类成员。

这个问题对我来说并不是一个真正的阻碍;在我的用例中,CD将作为同一补丁集的一部分实现,因此只需将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.

1 个答案:

答案 0 :(得分:2)

引用此SO answer

  

您只能在您的类型的实例中访问受保护的成员(或   从你的类型派生而来)。您无法访问受保护的成员   父母或堂兄类型的实例。

这意味着您可以从D访问this->xd.x(其中dD类型的另一个对象),而不是c.x即使cC类型的对象。

修复是将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 ); 

顺便说一句,这与共享指针无关。