Consider the stretch of code below:
#include <iostream>
using std::cout;
using std::string;
using std::endl;
class SuperPower{
private:
string name;
int category;
public:
string getName(){return name;}
int getCategory(){return category;}
SuperPower(string name, int category){
this->name = name;
this->category = category;
}
};
class Person{
private:
string name, nameRealLife;
SuperPower **powers;
SuperPower *powers2;
int nPowers;
protected:
Person(string name, string nameRealLife){
this->name = name;
this->nameRealLife = nameRealLife;
powers = new SuperPower*[4];
powers2 = new SuperPower[4]("",0);
nPowers = 0;
}
public:
~Person(){
delete []powers;
}
Person(const Person& p){
name = p.name;
nameRealLife = nameRealLife;
powers = new SuperPower*[4];
nPowers = p.nPowers;
for (int i=0;i<nPowers;i++)
powers[i] = p.powers[i];
}
string getName(){
return name;
}
bool addSuperPower(SuperPower &sp){
if (nPowers>=4)
return false;
powers[nPowers++] = &sp;
return true;
}
virtual double getTotalPower(){
double totalPower = 0;
for (int i=0;i<nPowers;i++){
totalPower += powers[i]->getCategory();
}
return totalPower;
}
};
...
My professor asked to solve a Objected Oriented Problem and I am struggling with the compiler to finish it because of this line:
powers2 = new SuperPower[4]("",0);
Trying to compile the code results in error: parenthesized initializer in array new [-fpermissive]
powers2 = new SuperPower4;
Why is it wrong? Isn't it just definning the constructor's parameters? Why does it happen? How should I fix it?
Do not use raw pointers. Use std::vector. It makes the life easier.
std::vector<SuperPower> powers2; // declaration
...
powers2(4, SuperPower("",0)), // in constructors's initialisation list
You can make it work by using: powers2 = new SuperPower[4]{{"", 0},{"", 0},{"", 0},{"", 0}}; instead of powers2 = new SuperPower[4]("",0); but don't do this, instead I insist you on using std::vector like this:
std::vector<Superpower> powers2;
and then in ctor:
powers2(4, Superpower("", 0));
Related
I am having trouble passing an array of object pointers from main() to a function from different class.
I created an array of object pointers listPin main() and I want to modify the array with a function editProduct in class Manager such as adding new or edit object.
Furthermore, I want to pass the whole listP array instead of listP[index]. How to achieve this or is there any better way? Sorry, I am very new to c++.
#include <iostream>
using namespace std;
class Product
{
protected:
string id, name;
float price;
public:
Product()
{
id = "";
name = "";
price = 0;
}
Product(string _id, string _name, float _price)
{
id = _id;
name = _name;
price = _price;
}
};
class Manager
{
protected:
string id, pass;
public:
Manager(string _id, string _pass)
{
id = _id;
pass = _pass;
}
string getId() const { return id; }
string getPass() const { return pass; }
void editProduct(/*array of listP*/ )
{
//i can edit array of listP here without copying
}
};
int main()
{
int numProduct = 5;
int numManager = 2;
Product* listP[numProduct];
Manager* listM[numManager] = { new Manager("1","alex"), new Manager("2", "Felix") };
bool exist = false;
int index = 0;
for (int i = 0; i < numProduct; i++) { //initialize to default value
listP[i] = new Product();
}
string ID, PASS;
cin >> ID;
cin >> PASS;
for (int i = 0; i < numManager; i++)
{
if (listM[i]->getId() == ID && listM[i]->getPass() == PASS) {
exist = true;
index = i;
}
}
if (exist == true)
listM[index]->editProduct(/*array of listP */);
return 0;
}
Since the listP is a pointer to an array of Product, you have the following two option to pass it to the function.
The editProduct can be changed to accept the pointer to an array of size N, where N is the size of the passed pointer to the array, which is known at compile time:
template<std::size_t N>
void editProduct(Product* (&listP)[N])
{
// Now the listP can be edited, here without copying
}
or it must accept a pointer to an object, so that it can refer the array
void editProduct(Product** listP)
{
// find the array size for iterating through the elements
}
In above both cases, you will call the function as
listM[index]->editProduct(listP);
That been said, your code has a few issues.
First, the array sizes numProduct and numManager must be compiled time constants, so that you don't end up creating a non-standard variable length array.
Memory leak at the end of main as you have not deleted what you have newed.
Also be aware Why is "using namespace std;" considered bad practice?
You could have simply used std::array, or std::vector depending on where the object should be allocated in memory. By which, you would have avoided all these issues of memory leak as well as pointer syntaxes.
For example, using std::vector, you could do simply
#include <vector>
// in Manager class
void editProduct(std::vector<Product>& listP)
{
// listP.size() for size of the array.
// pass by reference and edit the listP!
}
in main()
// 5 Product objects, and initialize to default value
std::vector<Product> listP(5);
std::vector<Manager> listM{ {"1","alex"}, {"2", "Felix"} };
// ... other codes
for (const Manager& mgr : listM)
{
if (mgr.getId() == ID && mgr.getPass() == PASS)
{
// ... code
}
}
if (exist == true) {
listM[index]->editProduct(listP);
}
You cannot have arrays as parameters in C++, you can only have pointers. Since your array is an array of pointers you can use a double pointer to access the array.
void editProduct(Product** listP){
and
listM[index]->editProduct(listP);
Of course none of these arrays of pointers are necessary. You could simplify your code a lot if you just used regular arrays.
Product listP[numProduct];
Manager listM[numManager] = { Manager("1","alex"), Manager("2", "Felix")};
...
for(int i = 0; i < numManager; i++ ){
if(listM[i].getId() == ID && listM[i].getPass() == PASS) {
exist = true;
index = i;
}
}
if(exist == true){
listM[index].editProduct(listP);
}
I am trying to create an array of objects in C++. As C++ Supports native objects like int, float, and creating their array is not a problem.
But when I create a class and create an array of objects of that class, it's not working.
Here is my code:
#include <iostream>
#include <string.h>
using namespace std;
class Employee
{
string name;
int age;
int salary;
public:
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
int getSalary()
{
return salary;
}
int getAge()
{
return age;
}
string getName()
{
return name;
}
};
int main(void)
{
Employee **mycompany = {};
//Create a new Object
mycompany[0] = new Employee(10, "Mayukh", 1000);
string name = mycompany[0]->getName();
cout << name << "\n";
return 0;
}
There is no compilation error, but when I'm running the Program, it is crashing. I don't know exactly what is happening here.
Please Help.
Here are some more details:
OS: 64bit Windows 8.1 on Intel x64 (i3) Architecture of Compiler: MinGW64 G++ Compiler
The advice here, as always, is to use some STL container, like an std::vector.
That said you're probably going to need a default Employee constructor (unless you always initialize all the elements of the container with the constructor you already have, which is unlikely what you'll do, if you are to manually allocate memory, but more likely if you use a std::vector).
//...
Employee() = default; // or Employee(){}
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
//...
If you really, absolutely, must do it by manual memory allocation, it would look roughly like this:
// Employee array with 5 employees, with the first two initialized with your constructor
Employee *mycompany = new Employee[5] {{10, "Mayukh1", 1000}, {20, "Mayukh2", 2000}};
//adding an employee
mycompany[2] = {30, "Mayukh3", 3000};
// it still has space for 2 more
Don't forget to delete the memory afterwards:
delete [] mycompany;
Live demo
this is how you would do that:
#include <iostream>
#include <string.h>
using namespace std;
class Employee
{
string name;
int age;
int salary;
public:
Employee(int agex, string namex, int salaryx)
{
name = namex;
age = agex;
salary = salaryx;
}
int getSalary()
{
return salary;
}
int getAge()
{
return age;
}
string getName()
{
return name;
}
};
int main(void)
{
//Create an Array length of 10
// in c++ its static you have to give the length of the array while declaring
Employee mycompany [10];
//Create a new Object
mycompany[0] = new Employee(10, "Mayukh", 1000);
string name = mycompany[0]->getName();
cout << name << "\n";
return 0;
}
I've a file including names and addresses to a Person Registry.
First I add the persons in my personArray, then I print them and finally Delete them.
So far, it works just fine.
Now Im trying to implement a Search()-function, where I can either find the name or the address of a person.
I call this in main()-function like this:
void SearchForPerson(PersonReg personReg)
{
Person *x1 = personReg.SearchForPerson("Jolina", nullptr);
Person *x2 = personReg.SearchForPerson("Olle", x1);
}
And I will be able to keep searcing for the Persons like this: (string search, pointer to the previous hit).
My function is close to empty. I have tried several things but nothing works.
I think I should somehow use this:
Person* PersonReg::SearchForPerson(std::string search, Person *person)
{
std::string s1 = search;
size_t foundName = s1.find(person->name);
size_t foundAddress = s1.find(person->adress);
if( /*hit*/)
{
//Print out FOUND
return person;
}
else
{
return nullptr;
}
}
My constructor to Person:
Person::Person(std::string _name, std::string _adress)
{
this->name = _name;
this->adress = _adress;
}
Anyone with an idea on how to continue this?
[EDIT]
I didnt show how i Stored my Persons, here it is: (PersonReg.cpp)
PersonReg::PersonReg(const int _maxSize)
{
this->maxSize = _maxSize;
personArray = new Person[_maxSize];
}
void PersonReg::AddPerson(Person *person)
{
this->personArray[indexInt++] = *person;
}
below i wrote a simple example to demonstrate the problem I experience. After executing the code, I get a cygwin exception 7200. I have looked around and tried a few things but to no resolve. Could somebody explain why do I get it, and how could I fix it? Appreciate your time, and many thanks in advance!
Code
#include <string>
#include <vector>
// string
using std::string;
// vector
using std::vector;
class Person{
private:
string name;
int age;
public:
Person(string& name, int& age);
};
Person::Person(string& name, int& age): name(name), age(age){}
int main(){
vector<Person> people;
string* names = new string[3];
names[0] = "bob";
names[1] = "alice";
names[2] = "hank";
int* ages = new int[3];
ages[0] = 10;
ages[1] = 20;
ages[2] = 30;
for(unsigned int i = 0; i < 3; ++i){
Person person(names[i], ages[i]);
people.push_back(person);
}
delete names;
delete ages;
return 0;
}
Error
0 [main] a 7200 cygwin_exception::open_stackdumpfile: Dumping stack
trace to a.exe.stackdump
P.S - I am relatively new to C++.
You need to delete arrays with delete[] rather than delete.
delete[] names;
delete[] ages;
I am new to C++ and practicing using vector as an object. However, I got an error "No matching constructor for initializing Employee" when I tried running the following program.
Please tell me how I could modify my program!
Also, when I write
staff[0] = Employee{"Harry Potter" 55000};
does this mean that I am storing string and double data in one of 10 open boxes in vector object of type Employee?
I apologize for such a basic question.
Thank you so much in advance!!
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Employee
{
public:
Employee(string, double);
double get_salaries();
string get_name();
void set_salaries(double);
private:
string name;
double salaries;
};
Employee::Employee(string n, double s)
{
name = n;
salaries = s;
}
double Employee::get_salaries()
{
return salaries;
}
string Employee::get_name()
{
return name;
}
void Employee::set_salaries(double s)
{
salaries = s;
}
int main()
{
// using vector as an object
int i;
vector<Employee> staff(10);
staff[0] = Employee{"Harry Potter", 55000};
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Your Employee class does not have a default, parameterless, constructor.
When you create the staff vector, it will create 10 Employee objects, thus invoking the default constructor.
To support this,
vector<Employee> staff(10);
you have to provide default constructor in your class.
Your main method
int main()
{
// using vector as an object
int i; // [i] not initialized anywhere.
vector<Employee> staff(10); // Incorrect way of declaring a vector
staff[0] = Employee{"Harry Potter", 55000}; // Incorrect way of creating a instance of class
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Change your main method like this
int main()
{
vector<Employee> staff;
staff.push_back(Employee("Harry Potter", 55000));
if (staff[0].get_salaries() < 100000)
cout << staff[0].get_salaries();
return 0;
}