这是编写指针数组的正确方法吗?

时间:2018-02-11 19:36:53

标签: c++

我有一个班级“员工” 我想为它创建一个指针数组。

这会有效吗?

Employee *employeeArr[size];

在我的“for循环”中有这样的东西

employeeArr[i] = new Employee(surname , firstname , gender); // constructor implemented Employee( para1, para2, para3)

或者我应该写

Employee *employeeArr = new Employee[size];

用“点”填充所有内容,如

employeeArr[i].setSurname(surname);

你能解释一下这个原因吗,我真的很擅长指点。第二个是别人告诉我的,但我无法得到一个答案,为什么我不能使用第一个。 如果可能的话,不要提到std :: array或std :: vector,我还是太新了

5 个答案:

答案 0 :(得分:4)

很抱歉让你大吃一惊:
您提供的所有示例都不应被视为"正确的方式" 来处理c ++中的类集合。

  

如果可能的话,不要提到std :: array或std :: vector,我还是太新了

不,那是牵引母马的错误道路。如果您无法掌握如何主要处理std::arraystd::vector,那么正确使用原始指针和原始数组肯定超出了您的能力范围。

假设您的Employee课程类似于

struct Employee {
    std::string surname_;
    std::string firstname_;
    enum Gender {
       Female = 'F' ,
       Male = 'M' ,
       Unxpecified = 'X'
    } gender_;
};

你有std::operator>>()

的重载
std::istream& operator>>(std::istream& is, Employee& employee) {
    char genderSymbol;
    is >> employee.surname_ >> employee.firstname_ >> genderSymbol;
    switch(genderSymbol) {
    case 'F':
    case 'M':
    case 'X':
         employee.gender_ = (Employee::Gender)genderSymbol;
         break;
    default:
        is.setstate(std::ios_base::failbit);
        break;
    }
}

表示Employee数组的一种好的和惯用的方法是使用

std::vector<Employee> employeeArr;

并将其填入循环:

Employee employee;
while(std::cin >> employee) {
    employeeArr.emplace_back(employee);
}

如果您确实需要指针(引用),可以考虑使用Dynamic Memory Management实用程序类提供的智能指针

例如,您可能决定拥有

std::vector<std::unique_ptr<Employee>> employeeArr;

并将其初始化为

while(std::cin >> surname >> firstname >> gender) {
    employeeArr.emplace_back(std::make_unique<Employee>(surname , firstname , gender));
}

如果您想要管理分层组织的类实例池,可以考虑这一点:

struct Employee {
    virtual ~Employee() {}
    std::string surname_;
    std::string firstname_;
    enum Gender {
       Female = 'F' ,
       Male = 'M' ,
       Unxpecified = 'X'
    } gender_;
};

struct IForeman : Employee {
    virtual std::vector<const Employee const*> TeamMembers() const = 0;
    virtual void AddTeamMember(const Employee const* member) = 0;
};

class Foreman : public IForeman {
     str::vector<const Employee const*> teamMembers_;
public:
     std::vector<const Employee const*> TeamMembers() const {
         return teamMembers_;
     }
     void AddTeamMember(const Employee const* member) {
         teamMembers_.push_back(member);
     }
};

考虑使用普通const指针分发相关连接的拥有或共享指针。

答案 1 :(得分:2)

  

如果可能的话,不要提到std :: array或std :: vector,我还是太新了

你倒退了。如果您太新,那么使用std::arraystd::vector。如果您是新手,请不要使用内置阵列,也不要进行手动内存管理。

你应该使用的是:

#include <array>
// ...
std::array<Employee, size> employeeArr;

如果在编译时知道size并且永远不会改变。如果在编译时不知道,或者数组需要动态增长,那么使用vector

#include <vector>
// ...
std::vector<Employee> employeeArr;

然后使用Employee添加push_back()个对象:

employeeArr.push_back(Employee(/* ... */));

这里也没有涉及指针。只是价值观。

一旦熟悉了容器,就可以深入研究C ++并了解指针和内存管理。

答案 2 :(得分:1)

第一个示例创建一个指向Employee个对象的指针数组,而第二个示例创建一个动态分配的Employee个数组。这些是完全不同的东西。

如果你不理解向量,你不应该搞乱指针,因为它们很容易被误用。如果您还没有{+ 3}},我建议您逐步学习C ++。

据我所知,在大多数情况下,静态数组的大小必须是一个常量表达式(能够在编译时计算)。这就是为什么你的第一个例子不起作用的原因。如果你想要大小未知的数组,那么你应该使用向量或动态数组。

一旦你理解了向量,你会发现它们比动态数组更方便,因为它们可以处理诸如为你自动释放内存之类的事情。向量的另一个好处是你可以在创建它们之后调整它们的大小。

答案 3 :(得分:0)

C ++是一种非常灵活的语言,决定完全属于你。

  1. 你可以创建一个指针数组(好吧,如果你这样做,内存处理将是完全手动的,并且容易出错)。
  2. 你可以创建一个指针向量(向量优于数组,因为它可以灵活地添加和删除而无需大量的手动代码编写)
  3. 你可以使用&#34;智能指针&#34;,这意味着智能指针的数组(或矢量作为更好的练习,(可能是矢量的智能指针)),这个智能指针处理为你记忆。
  4. 例如:

    vector<shared_ptr<Employee> > employees;
    employees.push_back(make_shared<Employee>(surname, firstname, gender));
    

    make_shared生成新创建的员工的(共享指针)。 共享指针是一个自动引用计数的指针,它在线程和共享不同对象之间的对象(指向对象)方面很有用。

    shared_ptr in CPP Reference

    unique_ptr in CPP Reference

    You can see this question for an example of using unique_ptr

答案 4 :(得分:0)

Employee *employeeArr[size];是一个Employee指针数组,因此大小是静态的,在编译时是已知的。而Employee *employeeArr = new Employee[size];是指向Employee对象的动态数组的指针;不是指针。

有所作为并谨慎使用。

您可以使用class vector与动态内存的分配无关。

以下是显示3种可能用法的示例:

#include <iostream>
#include <vector>
#include <string>


class Employee{
    public:
        Employee(){} // Imporatant for a dynamic array of objects
        Employee(const std::string, const std::string, const bool);

        void set(const std::string, const std::string, const bool);
        // some other methods here
        void print()const;

    private:
        std::string surName, firstName;
        bool  gender;
};

Employee::Employee(const std::string sur, const std::string first, const bool gend) : 
    surName(sur),
    firstName(first),
    gender(gend){

}

void Employee::set(const std::string sur, const std::string first, const bool gend){
    surName = sur;
    firstName = first;
    gender = gend;
}

void Employee::print()const{
    std::cout << "surName: " << surName << std::endl;
    std::cout << "firsName: " << firstName << std::endl;
    gender ? std::cout << "Male" : std::cout << "Female" ;
    std::cout << std::endl;
}


int main(){

    // 1: An array of pointers:
    Employee* empl[3];
    std::string surName, firstName;
    bool gender;

    for(auto i(0); i != 3; ++i){
        std::cout << "surName: ";
        std::cin >> surName;
        std::cout << "firstName: ";
        std::cin >> firstName;
        std::cout << "gender: ";
        std::cin >> gender;
        empl[i] = new Employee(surName, firstName, gender);
    }

    for(auto i(0); i != 3; ++i)
        empl[i]->print();

    std::cout << "_________________________" << std::endl;

    // 2: A pointer to a dynamic array:

    Employee* empl2 = new Employee[3]; // default constructor is imortant here
    for(auto i(0); i != 3; i++){
        std::cout << "surName: ";
        std::cin >> surName;
        std::cout << "firstName: ";
        std::cin >> firstName;
        std::cout << "gender: ";
        std::cin >> gender;
        empl2[i].set(surName, firstName, gender);
    }

    for(auto i(0); i != 3; ++i)
        empl2[i].print();

    delete[] empl2;

    std::cout << "_________________________" << std::endl;

    // 3: with vectors:

    std::vector<Employee> vecEmpl; // default ctor is not important here

    for(auto i(0); i != 3; ++i){
        std::cout << "surName: ";
        std::cin >> surName;
        std::cout << "firstName: ";
        std::cin >> firstName;
        std::cout << "gender: ";
        std::cin >> gender;

        Employee emp(surName, firstName, gender);
        vecEmpl.push_back(emp);
    }

    for(auto i(0); i != 3; ++i)
        vecEmpl[i].print();


    std::cout << std::endl << std::endl;
    return 0;
}