我正在学习C ++,我正在尝试使用其他语言编程的知识来理解C ++,这似乎让我感到困惑。我正在研究一个基本的套接字程序,并试图找出处理套接字类创建的最佳方法,这样我就可以读/写并只连接一次。
在我的其他语言中,我会创建一个静态对象类,允许我引用它,如果没有创建,我会创建套接字并连接。如果它已创建,我只会将其返回以进行引用。
但是一个类不能是一个静态类(至少这是我读过的那个)所以我回过头来看下一个我知道哪个是Singleton的选项。
所以我最终得到了像
这样的东西class Socket{
static Socket* socket;
public:
Socket& Get()
{
if (!socket) socket = new Socket;
return *socket;
}
};
我会在构造函数中有我的开始/连接内容。但这是假设要做的吗?互联网上似乎有很多相互矛盾的东西。例如,使用人们使用互斥锁,有些人使用模板。
哪种方式最适合套接字包装类?
答案 0 :(得分:2)
试试这个:
class Socket{
public:
static Socket& Get()
{
static Socket* socket = new Socket;
return *socket;
}
};
甚至:
class Socket{
public:
static Socket& Get()
{
static Socket socket;
return socket;
}
};
在访问器内声明静态单例套接字实例可防止初始化顺序与其他静态变量“see here”冲突。此外,C ++ 11保证以线程安全的方式(see here)初始化静态局部变量。
我还应该指出单身人士的使用是相对有争议的,详见this question。就个人而言,我建议只使用单例作为具有较少依赖关系的只读结构,其生命周期是该过程的生命周期(即没有取消初始化)。
答案 1 :(得分:1)
稍微不清楚你真正想要达到的目标,但一般来说你不需要/需要静态或单身。单身人士通常被视为bad。很可能你想用另一种方法做得更好。
请分享您的目标是建立什么,并且更容易为您提供更好的指导。
我认为“持久对象”一词在这里不清楚你的意思。可以从任何地方访问吗?或者可能在整个程序执行期间可用?如果它是前者,它可能是单身/单一模式。如果是后者,它可能是其他东西,比如将一个物体传递到需要它的所有地方。看一下依赖注入,这是一个很好的模式,可以解耦并构建可测试的代码。
答案 2 :(得分:1)
静态类和单例只是拥有全局变量和函数的不同方法。全局变量通常是个坏主意。如果你想要一个由系统的许多不同部分共享的套接字,那么你应该在某处本地创建一个套接字(例如,在main()
中),然后将它传递给需要共享它的组件。
如果你坚持使用全局变量,那么我可能只是坚持使用最简单的方法:声明并使用全局变量,而不是单例或静态类或类似的东西。
以下是制作全局变量和函数的每种方法的示例。
“静态类”是一个类,其成员在没有实例对象的情况下被访问。
C ++类可以包含所有静态成员,但是没有办法声明一个类,以禁止非静态成员。
class StaticClass {
public:
static Socket aStaticDataMember;
static void aStaticFunction() {}
}
Socket StaticClass::aStaticDataMember = Socket(...);
int main() {
StaticClass::aStaticFunction();
StaticClass::aStaticDataMember.doWhatever();
}
// in a header
extern Socket globalVariable;
void globalFunction();
// in a cpp file
Socket globalVariable;
void globalFunction() {}
int main() {
globalVariable.doWhatever();
globalFunction();
}
在C ++中有很多不同的方法可以做单例,但这是一种方式:
class SingletonClass {
public:
void doWhatever() {}
private:
// ... private members to implement singleton.
// If you define any constructors they should be private
friend SingletonClass &getSingletonClass() {
static SingletonClass singleton; // thread safe in C++11
return singleton;
}
}
int main() {
getSingletonClass().doWhatever();
}
以下是不使用全局变量的示例:
class ComponentAThatUsesASocket {
private:
Socket &socket;
public:
ComponentAThatUsesASocket(Socket &s) : socket(s) {}
void foo() {
socket.doWhatever();
}
}
int main() {
Socket socket;
ComponentAThatUsesASocket componentA(socket);
componentA.doWhatever();
ComponentB componentB(socket);
componentB.doWhatever();
}