C++11 似乎不可能通过 shared_ptr 访问 protected 成员

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

<分区>

看起来不可能通过 shared_ptr 访问 protected 成员。这是一个无法编译的最小示例:

// 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 派生自 C,但 D 无法访问 x 似乎很奇怪,而且我一直认为派生类可以使用 protected 基类成员。

这个问题对我来说并不是真正的障碍;在我的用例中,CD 将作为同一补丁集的一部分来实现,因此只需制作 x 就足够了public 作为解决方法。但是是否有更“惯用”的方式来使这段代码工作?

以防万一这是一个 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.

最佳答案

引自此SO answer :

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.

这意味着您只能从 D 访问 this->xd.x(其中 d 类型的另一个对象D),而不是 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 ); 

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

关于C++11 似乎不可能通过 shared_ptr 访问 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33505847/

相关文章:

c++ - in(std::cin) :这是什么意思?

c++ - 分隔整数部分和小数部分的代码

c# - 推荐程序结构

c# - 库存控制系统的类结构

c++ - 返回所选类型的元组的类型函数

c++ - 如何链接树中同一级别的所有节点

c++ - 编程语言为派生类重新定义方法的能力是什么?

c++ - 在 c++0x 中使用 __thread

javascript - OOP Javascript - 引用错误

c++ - 为什么 `explicit` 与 `virtual` 不兼容?