一个类中的c ++动态结构

时间:2014-04-18 20:20:51

标签: c++ class dynamic struct

我还在尝试学习C ++,而我的第一种方法来自C的非对象方面。所以我想重做我的结构并使用类数据结构。我想出了这个。

在Gradebook.h中

class Gradebook {
public:
//default constructor, initializes variables in private
Gradebook();
//accessor constructor, access members in private
private:
struct Student {
    int student_id;
    int count_student;
    string last;
    string first;
    };
struct Course {
    int course_id;
    int count_course;
    string name;
    Student *students;
    };
};

在我的Gradebook.cpp

Gradebook::Gradebook() {

 Course *courses = new Course;
 courses->students = new Student;

 courses->count_course = 0;
 courses->course_id = 0;

 courses->students->count_student = 0;
 courses->students->student_id = 0;

}

我的设计

我想动态创建x_amountStudentsx_amount Courses

问题

我不明白如何访问我的结构,所以我可以开始在我的结构中添加课程和学生。

我相信如果我可以尝试访问我的结构并操纵其中的成员,我可以完成其余的工作。我试过了:

void Gradebook::newCourse(Course *courses) {

  //do stuff

}

当我尝试编译它时,我会遇到各种错误:

In file included from gradebook.cpp:2:
./gradebook.h:9:18: error: C++ requires a type specifier for all declarations
        void newCourse(&Course);

gradebook.cpp:39:17: error: out-of-line definition of 'newCourse' does not match any
      declaration in 'Gradebook'
void Gradebook::newCourse(Course *courses) {


2 errors generated.
In file included from main.cpp:4:
./gradebook.h:9:18: error: C++ requires a type specifier for all declarations
        void newCourse(&Course);

对此菜鸟的任何帮助表示赞赏。提前谢谢!

2 个答案:

答案 0 :(得分:0)

StudentCourse被声明为私有结构,因此您无法直接访问它们。

您有三种选择;

  1. 将单独的第一类对象作为自己的类。
  2. Gradebook具有可以创建和操作StudentsCourses的界面。
  3. 在成绩册中制作学生和课程公共结构

答案 1 :(得分:0)

您的整个设计可以使用一些工作。

你的结构应该自己初始化。它们在Gradebook之外也是有意义的。

以下是执行此操作的“C ++方式”示例:

首先请注意std::vector是一个动态数组。而不是不必要地管理自己的内存,而是使用std::vector。要使用std::vector,您需要将#include <vector>放在文件顶部的某处。

对于Student,我们删除了count_student变量。容器应该跟踪学生的数量。 Student现在也通过构造函数初始化自己的值。请注意我如何使用constructor initialization list

struct Student 
{
    Student () ;

    int student_id;
    std::string first;
    std::string last;
};

Student::Student () : student_id (0)
{
}

我们为Course做类似的事情。再一次,重要的是Course正在初始化和管理自己的变量。

struct Course 
{
    Course () ;

    int course_id;
    std::string name;
    std::vector <Student> students;
};

Course::Course () : course_id (0)
{
}

现在简化了Gradebook类。请注意NewCourse如何使用reference代替指针。

class Gradebook {
public:
    Gradebook () ;

    void NewCourse (const Course &course) ;

private:
    std::vector <Course> courses;
};

Gradebook::Gradebook ()
{
}

void Gradebook::NewCourse (const Course &course)
{
    courses.push_back (course) ;
}

其他想法

我可能会从std::vector <Student> students;中取出Course。虽然是的,一门课程可能有很多学生,一个学生也可能会参加很多课程。这种多对多的关系可能会导致头痛,也可能不会。但

this link中描述了处理此问题的一种方法。另一种方法是必须建立存储学生和课程对的结构。

<强>更新

以下是std::vector::push_back的函数签名:

void push_back (const value_type& val);

如您所见,该函数返回void,因此您无法执行courses.push_back(id_number)->course_id之类的操作。此函数仅将对象插入向量中。

以下是如何将std::vectorStudent结构一起使用的示例。首先,为了使事情变得更容易,我将向Student添加一个新的构造函数。请注意,我还将student_id更改为id,以最大限度地减少冗余。

struct Student 
{
    Student () ;
    Student (const int id, const std::string &first, const std::string &last) ;

    int id;
    std::string first;
    std::string last;
};

Student::Student () : id (0)
{
}

Student::Student (const int id, const std::string &first, const std::string &last)
    : id (id), first (first), last (last)
{
}

以下是如何使用矢量的示例。

int main (void)
{
    // Create some students.
    Student s1 (1, "Bob", "Smith") ;
    Student s2 (2, "Katy", "Adams") ;
    Student s3 (3, "Mary", "Williams") ;

    // Create vector of students.
    std::vector <Student> students ;

    // Insert the students into the vector.
    students.push_back (s1) ;
    students.push_back (s2) ;
    students.push_back (s3) ;

    // Go through the students and print out data.
    for (unsigned n = 0; n < students.size (); ++n) {
        // Grab a reference to one of the students.
        Student &student = students [n] ; 

        // Print out information, be sure to #include <iostream> somewhere.
        std::cout << "ID: " << student.id
            << ", Name: " << student.first << " " << student.last << "\n" ;
    }

    // To update Bob's name to Rob.
    students [0].first = "Rob" ;

    return 0 ;
}