C++11 似乎不可能通过 shared_ptr 访问受保护的成员
C++11 seems impossible to access a protected member through a 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
派生自 C
,但 D
无法访问 x
似乎很奇怪,我一直认为派生的 [=34] =] 可以使用 protected
基础 class 成员。
这个问题对我来说并不是真正的障碍;在我的用例中,C
和 D
将作为同一补丁集的一部分实施,因此只需将 x
public 作为解决方法就足够了。但是是否有更多 "idiomatic" 方法来使此代码正常工作?
以防这是一个 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->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 );
顺便说一句,这与共享指针无关。
看起来无法通过 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
派生自 C
,但 D
无法访问 x
似乎很奇怪,我一直认为派生的 [=34] =] 可以使用 protected
基础 class 成员。
这个问题对我来说并不是真正的障碍;在我的用例中,C
和 D
将作为同一补丁集的一部分实施,因此只需将 x
public 作为解决方法就足够了。但是是否有更多 "idiomatic" 方法来使此代码正常工作?
以防这是一个 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->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 );
顺便说一句,这与共享指针无关。