Is this the correct way to write an array of pointers?

I have an Employee class. I want to create an array of pointers for them.

Will this work?

Employee *employeeArr[size]; 

In my "for loop" something like this

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

OR should be written

 Employee *employeeArr = new Employee[size]; 

And fill everything with "dots", for example

 employeeArr[i].setSurname(surname); 

Could you explain the reason, I'm really new to pointers. The second was told to me by someone else, but I could not get an answer about why I can not use the first. Also, if possible, don't mention std :: array or std :: vector, I'm still too new

+5
source share
5 answers

Sorry to surprise you:
None of the examples you cited should be considered as the β€œright way” to handle class sets in C ++.

Also, if possible, don't mention std :: array or std :: vector, I'm still too new

No, this is the wrong way to raise a mare. The proper use of source pointers and raw arrays certainly goes beyond your capabilities if you cannot figure out how to handle std::array or std::vector in the first place.


Suppose your Employee class looks like

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

and you have overload for 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; } } 

One good and idiomatic way to represent an Employee array is to use

 std::vector<Employee> employeeArr; 

and fill it in the loop:

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

If you really need pointers (links), you can use smart pointers, as provided in the Dynamic Memory Management utility .

For example, you can choose

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

and initialize it as

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

This is taken into account if you want to manage pools of hierarchically organized instances of a class, for example:

 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); } }; 

Consider passing in owned or shared pointers to related connections using simple const pointers.

+4
source

Also, if possible, don't mention std :: array or std :: vector, I'm still too new

You got it back. If you are too new, you should use std::array and std::vector . Do not use built-in arrays and do not perform manual memory management if you are a beginner.

What you should use is:

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

if size known at compile time and never changes. If it is not known at compile time or the array should grow dynamically, use vector :

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

and then add the Employee objects to it using push_back() :

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

And there are no pointers here. Just meanings.

Once you become familiar with containers, you can dive deeper into C ++ and learn about pointers and memory management.

+2
source

The first example creates an array of pointers to Employee objects, and the second creates a dynamically allocated array of Employee s. These are completely different things.

If you do not understand vectors, you should not bother with pointers because they are easy to use. I would recommend learning C ++ step by step with a good book , if you don't already have one.

As far as I know, in most situations, the size of the static array should be a constant expression (which can be calculated at compile time). That is why your first example does not work. If you need arrays with an unknown size, you should use vectors or dynamic arrays.

Once you understand the vectors, you will realize that they are much more convenient than dynamic arrays, since they handle things like automatically freeing memory for you. Another nice thing about vectors is that you can resize them after they are created.

+1
source

C ++ is a very flexible language, and the solution is completely yours.

  • You can create an array of pointers (well, if you do, memory processing will be completely manual and error prone).
  • You can create a vector of pointers (a vector is better than an array in that it is flexible to add and remove without a lot of writing code manually).
  • You can use smart pointers, which means an array (or vector as a best practice (and possibly a smart pointer of a vector)) of smart pointers, these smart pointers process memory for you.

For instance:

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

make_shared creates (a generic pointer) a newly created employee. A shared pointer is a self-counting pointer that is great for streaming and sharing an object (pointer to an object) between different objects.

shared_ptr in CPP reference

unique_ptr in CPP Reference

You can see this question using unique_ptr as an example.

0
source

Employee *employeeArr[size]; is an array of Employee pointers, so the size is static, which is known at compile time. While Employee *employeeArr = new Employee[size]; is a pointer to a dynamic array of Employee objects; not pointers.

Make a difference and use them carefully.

You can use class vector where allocatio-de-distribution of dynamic memory does not matter.

Here is an example showing 3 possible uses:

 #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; } 
0
source

Source: https://habr.com/ru/post/1275298/


All Articles