0

我无法使用参数包获取 2 个相同类型的不同对象以指向不同对象的指针。这是Controller.h:

using expand_type = int[];

template<typename... Ts> class Controller {
public:
    Controller(int i, string s, Ts... args): id(i), name(s) {
        expand_type{ (add_component(&args), 0)... };

    }
    void add_component(Test2* a) {
        device_.push_back(a);
    }
    void print() {
        cout<<name<<":"<<endl;
        cout<<"================="<<endl;
        for (vector<Test2*>::size_type i = 0; i < device_.size(); ++i) {
            cout<<device_[i]->print()<<endl;
        }
        cout<<"================="<<endl;
    }
private:
    vector<Test2*> device_;
    int id;
    string name;
};

这是我的Test2.h:

class Test2 {
public:
    Test2(): x(0) {}
    Test2(int a): x(a) {}
    int print() const {
        return x;
    }
private:
    int x;
};

我的问题是当我制作两个单独的 Controller 对象时,它们在各自的向量中共享它们的 Test2 对象。这是我的主要内容:

int main() {
    Test2 b(69);
    Test2 c(666);
    Test2 d(943754);
    Controller<Test2, Test2, Test2, Test2> x(2, string("Peter"), 70, b, c, d);
    Controller<> y(2, string("Pietje"));
    Controller<Test2, Test2, Test2, Test2> z(3, string("Jan"), 909, 808, 1, 2);

    x.print();
    y.print();
    z.print();

    cout<<"hello"<<endl;
    return 0;
}

那么输出是:

Peter:
=================
0
808
1
2
=================
Pietje:
=================
=================
Jan:
=================
0
808
1
2
=================
hello

我希望 Controller 的不同对象具有指向不同 Test2 对象的不同指针,而我 v3 不知道如何。

此外,作为一个附带问题;我的第一个指针总是变为 0,除非它是向量中唯一的对象。

任何帮助表示赞赏!

4

1 回答 1

0

避开时髦的行为,这里的主要问题是所有权:是否Controller拥有设备,如果不是谁?假设控制器不拥有这些设备。然后像这样的东西会引起问题

Controller<...> z(3, string("Jan"), 909, 808, 1, 2);
                                    ^^^ temporary object's lifetime ends immediately
                                        it won't have a valid address to point to

一旦你计划好了,你的体验会好很多。假设Controller拥有这些设备:只需使用一个向量即可Test2

下一个问题是可变参数模板。看起来device_s 都是相同的类型,可变参数模板的唯一用途是具有可变数量的构造函数参数。如果是这样,只需为构造函数使用可变参数模板,并使类成为普通的简单类型:

class Controller {
public:
    template<typename... Ts>
    Controller(int i, string s, Ts&&... args): id(i), name(s), device_ { std::forward<Ts>(args)... } { }
    // ...
};

把它们放在一起,一切都按预期工作:

#include <vector>
#include <string>
#include <iostream>
using namespace std;

class Test2 {
public:
    Test2(): x(0) {}
    Test2(int a): x(a) {}
    int print() const {
        return x;
    }
private:
    int x;
};

class Controller {
public:
    template<typename... Ts>
    Controller(int i, string s, Ts&&... args): id(i), name(s), device_ { std::forward<Ts>(args)... } { }

    void print() {
        cout<<name<<":"<<endl;
        cout<<"================="<<endl;
        for (auto& device : device_) {
            cout<<device.print()<<endl;
        }
        cout<<"================="<<endl;
    }
private:
    vector<Test2> device_;
    int id;
    string name;
};

int main() {
    Test2 b(69);
    Test2 c(666);
    Test2 d(943754);
    Controller x(2, string("Peter"), 70, b, c, d);
    Controller y(2, string("Pietje"));
    Controller z(3, string("Jan"), 909, 808, 1, 2);

    x.print();
    y.print();
    z.print();

    cout<<"hello"<<endl;
    return 0;
}
Peter:
=================
70
69
666
943754
=================
Pietje:
=================
=================
Jan:
=================
909
808
1
2
=================
hello

演示:https ://godbolt.org/z/bLjgaf


更新:根据您的要求,假设Controller只存储原始指针并且不拥有Test2设备。首先,您必须将引用传递给构造函数,以便可以访问对象的地址:

class Controller {
public:
    template<typename... Ts>
    Controller(int i, string s, Ts&... args): id(i), name(s), device_ { &args... } { }
    // ...
};

然后你必须确保你传递给它的每个对象都比控制器寿命长:

Test2 b(69);
Test2 c(666);
Test2 d(943754);
Controller x(2, string("Peter"), b, c, d); // this is fine
Controller y(2, string("Pietje"));         // this is fine
Controller z(3, string("Jan"), 909, 808, 1, 2); // uh oh!

到目前为止,我们只讨论过堆栈分配的Test2对象。您还可以动态分配对象并获取指向它的指针。该指针只有一个所有者,您可以通过以下方式转让所有权std::move

std::unique_ptr<Test2> = std::make_unique<Test2>(42);

您还可以创建具有共享所有权的指针。您可以复制此指针,最后一个幸存的指针将清理对象:

std::shared_ptr<Test2> = std::make_shared<Test2>(42);

但是,如果您想了解内存模型,我不建议您这样做。很多时候,人们将其用作避免考虑记忆模型的一种方式。如果所有东西都有一个明确的所有者,它会让你的生活更轻松。

于 2019-12-24T17:56:09.930 回答