gpt4 book ai didi

c++ - 在 C++ 中只公开类实例

转载 作者:行者123 更新时间:2023-12-04 07:54:16 24 4
gpt4 key购买 nike

我正在尝试定义一个禁止显式实例化的类。
用户必须只能使用一组有限的实例。
在代码方面,我目前正在做这样的事情:

class Obj
{
private:
int _x;
Obj(int x) : _x() {}

public:
static const Obj obj1;
static const Obj obj2;
};

const Obj Obj::obj1(1);
const Obj Obj::obj2(2);

int main()
{
Obj o1 = Obj::obj1;
}
构造函数是私有(private)的,类实例可通过 Obj::xxx 获得.
但是,使用这种方法,我不喜欢一个实例从另一个实例可见的事实。
(即我不希望 Obj::obj1.obj2.obj1 成为有效语法)
是否有任何解决方法或更好的模式来避免这种行为?

最佳答案

公共(public)静态成员(函数或对象)总是能够在从该类的实例中查找的过程中找到——因此避免它的唯一方法是不提供这些作为 static您提供的类型的成员。
由于您要求保留Obj的构造函数私有(private),我们需要使用friend船舶 某处以便外部主体可以提供这些对象并访问 Obj的构造函数,但不属于 Obj 类型(这是允许链接的原因)。
出于这个原因,我建议使用辅助 classstruct输入以便它可以是 friend ed 允许它调用 Obj的构造函数:

class ObjConstants;
class Obj
{
// Note: friendship here so that ObjConstants can construct it
friend ObjConstants;
private:
int _x;
Obj(int x) : _x() {}
};

class ObjConstants {
public:
static const Obj obj1;
static const Obj obj2;
};
const Obj ObjConstants::obj1(1);
const Obj ObjConstants::obj2(2);

int main()
{
Obj o1 = ObjConstants::obj1;
}
这也可以是一个包含 static 的类。工厂功能:
class ObjConstants {
public:
static const Obj& getObj1();
static const Obj& getObj2();
};
甚至只是一堆 namespace范围内的工厂函数,每个函数都是单独的:
const Obj& getObj1();
const Obj& getObj2();

class Obj {
friend const Obj& getObj1();
friend const Obj& getObj2();
...
};
当您为静态对象使用外部持有者(无论是类型还是函数)时,对象的每次访问都会返回与持有者不同的类型(在本例中为 Obj ),这会阻止链接 obj1.obj2.obj1
还值得注意的是,这种方法也适用于 static constexpr。对象。你不能定义 static constexpr对象在其自己的类的主体中,因为该类在那时是不完整的,例如:
class Foo {
public:
static inline constexpr auto foo = Foo{}; // Error: 'Foo' is incomplete!
};
因此,使用辅助持有者类型(无论是 class 还是 namespace )可以使定义在那时完成:
class Foo { ... };
class FooConstants {
public:
static inline constexpr auto foo = Foo{...};
};

注:
一般来说,我建议反对 static const像这样具有外部链接的对象以避免静态初始化问题

关于c++ - 在 C++ 中只公开类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66784603/

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