在c++中维护选中的对象



为了更清晰,我想知道存储所选对象引用的最佳方法:

#include <iostream>
using namespace std;
class A{
public:
int a;
A(int b)
{
a=b;
}
};
class B{
public:
int b;
B(int a)
{
b=a;
}
};
int main() {
A a(1);
B b(2);
**<<some type>>** x= &a;
//cout<<x.a or x->a<<endl;
x = &b;
//cout<<x.b or x->b;
return 0;
}

用例:实际上,我正在解析一些格式化的字符串,并返回解析过的对象(类,A, B返回)。在解析字符串时,我知道要填充什么对象和填充什么字段,以保持此信息(在运行时更改),我正在寻找解决方案。这基本上为我节省了一个开关箱,并且应用程序是延迟敏感的。

所描述的用例听起来像一个抽象工厂模式。您解析一些内容,然后返回带有一些设置参数的适当类型。类型的决定将在运行时做出。通过使用多态性,您可以创建您想要的输出。

抽象工厂的标准问题是构造函数的签名必须相同。

但是使用下面显示的解决方案,您可以解析任何内容,然后实例化适当的类型并根据需要添加参数值。

请检查:

#include <iostream>
#include <map>
#include <utility>
#include <any>

// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Basen"; }
virtual void print() { std::cout << "Print Basen"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "n"; }
virtual ~Child1() { std::cout << "Destructor Child1n"; }
virtual void print() { std::cout << "Print Child1: " << data << "n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "n"; }
virtual ~Child2() { std::cout << "Destructor Child2n"; }
virtual void print() { std::cout << "Print Child2: " << data << "n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "n"; }
virtual ~Child3() { std::cout << "Destructor Child3n"; }
virtual void print() { std::cout << "Print Child3: " << data << "n"; }
};

using UPTRB = std::unique_ptr<Base>;

template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
factory.add(3, createClass<Child3, int, long, char, std::string>);

// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1;  const int ci = 1;   int& ri = i;    const int& cri = i;   int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}

如果答案不合适,请告知我,我将删除。

最新更新