0

首先我想说我对 CPP 很陌生(我从 cpp11 开始):) 考虑以下实体:学生(名字 + 姓氏)和组(描述 + 更多学生)。我在 C++ 中创建了以下 2 个类:

class Student
{
private:
    std::string firstName;
    std::string lastName;
    Student(const Student &student);
    Student& operator=(const Student &student);
public:
    Student():firstName(""), lastName("") { }
    Student(std::string firstName, std::string lastName):firstName(firstName), lastName(lastName) { }
    Student(const Student &&student):firstName(student.firstName), lastName(student.lastName) { }
    Student& operator=(const Student &&student) { this->firstName=student.firstName; this->lastName=student.lastName; return *this; }
    std::string GetFirstName() const { return this->firstName; }
    std::string GetLastName() const { return this->lastName; }
};


class Group
{
private:
    std::string description;
    std::vector<std::shared_ptr<Student>> students;
    Group(const Group &group);
    Group& operator=(const Group &group);
public:
    explicit Group():description(""), students(std::vector<std::shared_ptr<Student>>()) { }
    explicit Group(std::string description) :description(description), students(std::vector<std::shared_ptr<Student>>()) { }
    void NewStudent(Student &&student) { students.push_back(std::make_shared<Student>(std::move(student))); }
    std::vector<std::shared_ptr<Student>> GetStudents() const { return students; }
};

主要我有这个:

Student s1("fn1","ln1");
Student s2("fn2","ln2");
//Student s3("fn3","ln3");
Group cppGroup("C plus plus");
cppGroup.NewStudent(std::move(s1));
cppGroup.NewStudent(std::move(s2));
cppGroup.NewStudent(Student("fn3", "ln3"));
//cppGroup.NewStudent(s3);
std::vector<std::shared_ptr<Student>> cppStudents=cppGroup.GetStudents();

我的问题与 NewStudent 方法有关。在前两种情况下,参数是 move(s),在第三种情况下是 Student(...)。我的猜测是 Student("fn3", "ln3") 与 Student s3("fn3, "ln3") 相同,但是如果我将 s3 传递给函数,它将无法编译并出现以下错误:无法从学生对学生&&

PS:如果您帮助我了解如何制作我认为理想的示例,我将不胜感激。非常感谢你。

LE:我想我明白发生了什么,Visual Studio 显示以下错误:无法将左值转换为右值,所以我的猜测是,如果我传递给 NewStudent s3,它不知道如何将其转换为右值,但如果我如果将调用移动构造函数,则传递它 Student("fn3", "ln3")。

4

3 回答 3

1

如果这确实是您的设计,您可以对其进行大量简化并取消所有智能指针和自定义结构:

class Student
{
private:
    std::string firstName;
    std::string lastName;
public:
    Student(std::string firstName, std::string lastName):firstName(firstName), lastName(lastName) { }
    std::string GetFirstName() const { return this->firstName; }
    std::string GetLastName() const { return this->lastName; }
};


class Group
{
private:
    std::string description;
    std::vector<Student> students;
public:
    explicit Group(std::string description) :description(description) { }
    void NewStudent(Student student) { students.push_back(student); }
    std::vector<Student> GetStudents() const { return students; }
};
于 2013-01-20T00:14:17.850 回答
0

我建议更改您的设计并使用智能指针。

为所有学生准备一个容器。

学生将在“所有学生”容器中拥有一个或多个指向学生的智能指针。

这种设计允许您在不复制学生对象的情况下拥有不同的主题组。Group contains 将包含智能指针的副本。

使用此设计,您还可以创建索引以按不同标准对学生进行排序。例如,您可以有一个按名字排序的学生索引和另一个按姓氏排序的学生索引。

于 2013-01-19T23:15:26.833 回答
0

Student("fn3", "ln3") 是一个没有名字的临时对象。编译器决定它可以放弃它,因为你没有机会再次使用它。在 Student s2("fn2","ln2") 的情况下,您将引用变量 s2 中的对象。所以你必须用 move 语句明确地放弃它。

于 2013-01-19T23:47:11.220 回答