Tra*_*les 1 c++ templates pointers vector
我目前希望有一个对象向量,其中每个对象具有不同的属性.
预期结果:
//v is a vector
v.push_back(ttSaveObj(5, "int example"));
v.push_back(ttSaveObj("Hello, world!", "string example"));
std::cout << v[0].data << " " << v[0].variableName << std::endl; //Intended Output: 5 int example
std::cout << v[1].data << " " << v[1].variableName << std::endl; //Intended Output: Hello, world! string example
Run Code Online (Sandbox Code Playgroud)
根据这个答案,我尝试<void*>在模板中为类创建一个构造函数,但这似乎只是创建一个指针void(正如我部分预期的那样).
ttSaveObj.hpp:
template <typename T>
class ttSaveObj {
public:
ttSaveObj(T pVar, std::string pName) {
data = pVar;
variableName = pName;
};
~ttSaveObj() {};
std::string variableName;
T data;
};
Run Code Online (Sandbox Code Playgroud)
ttGameObj.hpp:
#include "ttSaveObj.hpp"
class ttGameObj {
public:
ttGameObj();
~ttGameObj();
std::vector<ttSaveObj<void*>> data;
};
Run Code Online (Sandbox Code Playgroud)
ttGameObj.cpp:
#include "ttGameObj.hpp"
ttGameObj::ttGameObj() {
int asdf = 5;
int * test = &asdf;
data.push_back(ttSaveObj<void*>(test, "X"));
std::cout << &data[0].data << " " << data[0].variableName << std::endl; //Output: 0x15fb770 X
}
Run Code Online (Sandbox Code Playgroud)
感谢所有能帮助我更接近我的预期结果的东西!
放在向量中的对象似乎有两个数据成员:variableName具有固定std::string类型的数据,以及具有不同类型的data字段.
您可以考虑在该字段中使用C++ 17std::variant(或Boost的variant实现)data.例如,如果您计划支持的类型int,float并std::string为您的data,您可以使用 std::variant<int, float, std::string>.
还有std::any,如果你想存储的情况下,任何类型(即满足中所述的要求std::any的文档).
在现代 C++中,我建议避免使用C风格void*,并且仅在严格必要时使用它(例如,如果您处于某些传统的C API边界):有更安全,更强大和更高级别的替代方案.
另一个选项(如果它对您的设计更有意义)是为要放入向量中的对象定义基类(接口),并定义实现此接口的自定义类.在这种情况下,我建议使用智能指针(如eg std::unique_ptr或std::shared_ptr)以简单和安全的方式管理这些对象(我在这里看到另一个使用原始指针的答案,需要显式new/ delete- 实际上在代码中有news但是没有delete,随之而来的资源泄漏).
例如:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;
// Interface for an element to be inserted in the vector
class IElement
{
public:
IElement() {}
virtual ~IElement() {}
virtual string ToString() = 0;
// Other virtual methods ...
};
class IntElement : public IElement
{
public:
explicit IntElement(int n) : _n{ n } {}
virtual string ToString() override
{
return to_string(_n);
}
private:
int _n;
};
class StringElement : public IElement
{
public:
explicit StringElement(const string& s) : _s{ s } {}
virtual string ToString() override
{
return _s;
}
private:
string _s;
};
int main()
{
vector<shared_ptr<IElement>> elements;
elements.push_back(make_shared<IntElement>(10));
elements.push_back(make_shared<IntElement>(20));
elements.push_back(make_shared<StringElement>("Hello"));
elements.push_back(make_shared<StringElement>("World"));
for (const auto& e : elements)
{
cout << e->ToString() << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)10 20 Hello World