我有一个班级“员工” 我想为它创建一个指针数组。
这会有效吗?
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,我还是太新了
答案 0 :(得分:4)
很抱歉让你大吃一惊:
您提供的所有示例都不应被视为"正确的方式" 来处理c ++中的类集合。
如果可能的话,不要提到std :: array或std :: vector,我还是太新了
不,那是牵引母马的错误道路。如果您无法掌握如何主要处理std::array
或std::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::array
和std::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 ++是一种非常灵活的语言,决定完全属于你。
例如:
vector<shared_ptr<Employee> > employees;
employees.push_back(make_shared<Employee>(surname, firstname, gender));
make_shared
生成新创建的员工的(共享指针)。
共享指针是一个自动引用计数的指针,它在线程和共享不同对象之间的对象(指向对象)方面很有用。
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;
}