gpt4 book ai didi

C++ 私有(private)访问其他类的成员

转载 作者:太空宇宙 更新时间:2023-11-04 12:13:06 25 4
gpt4 key购买 nike

我正在使用 boost::asio 编写多线程服务器(用于 socket ),boost::thread (用于线程),libconfig++ (用于读取配置文件)和 protocol buffers (用于协议(protocol)实现)。

服务器或多或少遵循这条路线:main() -> 创建一个应用程序对象 -> 运行应用程序对象。应用程序加载配置文件,然后创建服务器对象(作为常量传递给配置类)。服务器对象配置自身并绑定(bind)端口,开始接受,等等。每当检测到新客户端时,服务器都会创建一个新的客户端对象,然后创建一个线程来运行客户端的连接处理程序。

所有这些都是为了说明配置文件是从我的 Application 类加载的,然后一路向下传递到我的 Client 类。如果将 libconfig 对象直接传递给客户端,这应该不会造成任何问题,但众所周知,多线程意味着当两个或多个线程同时访问时内存会损坏。

The way to solve this was discussed in other post并最终实现了一个自动解决互斥锁问题的包装器。

魔法课

应用配置.h

#ifndef _APP_CONFIG_H_
#define _APP_CONFIG_H_ 1

#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/noncopyable.hpp>
#include <libconfig.h++>
#include <string>

namespace BBCP {
namespace App {

class ConfigLock;

class Config {
public:
friend class BBCP::App::ConfigLock;

Config(std::string const &file) :
cfg(new libconfig::Config()),
mutex(new boost::mutex())
{
cfg->readFile(file.c_str());
}

private:
boost::shared_ptr<libconfig::Config> cfg;
boost::shared_ptr<boost::mutex> mutex;
};

class Server;
class Client;

class ConfigLock : boost::noncopyable {
public:
ConfigLock(BBCP::App::Config const &wrapper) :
cfg(wrapper.cfg),
mutex(wrapper.mutex),
lock(new LockType(*mutex))
{ }

libconfig::Config &get() throw() { return *cfg; };
private:
boost::shared_ptr<libconfig::Config> cfg;
boost::shared_ptr<boost::mutex> mutex;

typedef boost::lock_guard<boost::mutex> LockType;
boost::shared_ptr<LockType> lock;
};

}
}

#endif

对于懒惰的人来说,这个类包含......好吧,两个类(讽刺?):BBCP::App::ConfigBBCP::App::ConfigLockBBCP::App::Config 只是加载一个文件,而 BBCP::App::ConfigLock 需要一个 BBCP::App::Config作为参数,然后锁定 BBCP::App::Config 的互斥锁。创建锁后,调用 BBCP::App::ConfigLock::get,它返回对 libconfig::Config 对象的引用!

问题

嗯:

服务器.cpp:

void BBCP::App::Server::startAccept() {
newClient.reset(new BBCP::App::Client(io_service, config_wrapper));
acceptor.async_accept(newClient->getSocket(), boost::bind(&BBCP::App::Server::acceptHandler, this, boost::asio::placeholders::error));
}

此函数创建一个新的客户端对象,加载了 boost::asio::io_service 对象和 BBCP::App::Config 对象。

服务器.cpp

void BBCP::App::Server::acceptHandler(boost::system::error_code const &e) {
if (!acceptor.is_open()) {
// ARR ERROR!
return;
}

if (!e) {
client_pool.create_thread(*newClient);
}
else {
// HANDLE ME ERROR
throw;
}

startAccept();
}

此函数会创建一个新线程或(尚未实现)错误,以防...好吧,错误,然后再次启动接受循环。

在这部分之前,客户端代码大多无关紧要:

客户端.cpp:

void BBCP::App::Client::parseBody() {
BBCP::Protocol::Header header;
BBCP::Protocol::Hello hello;
boost::scoped_ptr<BBCP::App::ConfigLock> lock;
libconfig::Config *cfg;

(...)

switch ((enum BBCP::Protocol::PacketType)header.type()) {
case BBCP::Protocol::HELLO:
(...)

// config_wrapper is a private variable in the client class!
lock.reset(new BBCP::App::ConfigLock(config_wrapper));

// ARRRRRRR HERE BE DRAGOONS!!
*cfg = lock->get();

(...)

lock.reset();
break;
(...)

}

(...)
}

说实话,没想到会出现这种错误:

/usr/include/libconfig.h++: In member function ‘void BBCP::App::Client::parseBody()’:
/usr/include/libconfig.h++:338:13: error: ‘libconfig::Config& libconfig::Config::operator=(const libconfig::Config&)’ is private
client.cpp:64:30: error: within this context
client.cpp:71:21: error: request for member ‘exists’ in ‘cfg’, which is of non-class type ‘libconfig::Config*’
client.cpp:77:51: error: request for member ‘lookup’ in ‘cfg’, which is of non-class type ‘libconfig::Config*’

但就是这样,我需要一些方法来解决它:(。我试过让 BBCP::App::Client 成为 BBCP::App 的友元类: :ConfigLock,但随后它变成了这样:

In file included from ../include/app_config.h:4:0,
from ../include/app_main.h:6,
from main.cpp:18:
../include/app_client.h:15:53: error: ‘BBCP::App::Config’ has not been declared
In file included from ../include/app_config.h:4:0,
from ../include/app_main.h:6,
from main.cpp:18:
../include/app_client.h:32:5: error: ‘Config’ in namespace ‘BBCP::App’ does not name a type
In file included from ../include/app_config.h:4:0,
from ../include/app_main.h:6,
from main.cpp:18:
../include/app_client.h: In constructor ‘BBCP::App::Client::Client(boost::asio::io_service&, const int&)’:
../include/app_client.h:15:120: error: class ‘BBCP::App::Client’ does not have any field named ‘config_wrapper’

然后我像 O_O 一样去了,所以我就放弃了,来到这里,再次寻求一些 über C++ 大师 hackz0r 的帮助,并责备试图访问另一个类的私有(private)成员这样的错误行为。

最佳答案

首先要弄清楚自己的方向是否正确,下一步就是到达那里。

为什么Config类型的赋值运算符是private的?默认情况下,编译器生成的赋值运算符是公共(public)的,所以如果它被声明为私有(private)的,很可能是对象不被复制的原因,否则你应该把它公开,问题就不再是问题了.

关于添加友元声明后的特定问题,这似乎表明您错过了包含声明/定义 Config 类型的 header 。然后代码中有更多错误(一个尚未定义的成员 - 先前错误的结果?),或者在原始代码中试图访问指针引用的对象而不取消引用它...

关于C++ 私有(private)访问其他类的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8997319/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com