It keeps me getting this error in Event.h:
field ‘group’ has incomplete type ‘Group’
For context, I want to have a class Group which has an owner (from class Person) and it consists of a vector of people (class Person):
Group.h
class Person;
#include "Person.h"
Class Group
{
private:
std::string name;
std::vector<Person> people;
int size = 0;
Person owner;
public:
Group(Person owner);
~Group();
}
In the Person class, I want to have just a vector of lists (class List, not important for this specific error). Note that in the Person class I have a constructor Person(int id);
In the Event class, I want to have a group of people invited that can be saved as a Group class:
Event.h
class Group;
#include "Group.h"
class Event
{
private:
std::string tittle;
std::string description;
bool locked;
bool checked;
Group group;
public:
Event(std::string tittle);
~Event();
}
Why can't I have a Person owner on my group?
Edit:
I don't know why, but now it works. I guarded everything with just #pragma once and maybe I changed something in the way I compiled. Thanks for all answers :)
You are defining something out of order. Perhaps the #ifdef guards.
This compiles just fine:
class Person {};
class Group
{
private:
std::string name;
std::vector<Person> people;
int size = 0;
Person owner;
public:
Group( Person owr );
~Group();
};
class Event
{
private:
std::string tittle;
std::string description;
bool locked;
bool checked;
Group group;
public:
Event(std::string tittle);
~Event();
};
Godbolt: https://godbolt.org/z/f785vK1dq
The following works fine for me (Online Demo):
Person.h
#ifndef Person_H
#define Person_H
class Person
{
};
#endif
Group.h
#ifndef Group_H
#define Group_H
#include "Person.h"
#include <string>
#include <vector>
class Group
{
private:
std::string name;
std::vector<Person> people;
int size = 0;
Person owner;
public:
Group(Person owner) : owner(owner) {}
};
#endif
Event.h
#ifndef Event_H
#define Event_H
#include "Group.h"
#include <string>
class Event
{
private:
std::string tittle;
std::string description;
bool locked = false;
bool checked = false;
Group group;
public:
Event(std::string tittle) : tittle(tittle), group(Person{}) {}
};
#endif
main.cpp
#include <iostream>
#include "Event.h"
int main()
{
Event evt("title");
return 0;
}
Related
Hello so i want to create a header file class which name testing and also its cpp but for some reason this is inaccessible i dont know why
testing.h
#ifndef TESTING_H
#define TESTING_H
#include <string>
using namespace std;
class testing
{
string Name;
void printname(string name);
};
#endif
testing.cpp
#include <iostream>
#include "testing.h"
using namespace std;
void testing::printname(string name) // inaccessible in my main i dont know what reason :(
{
Name = name;
cout<<Name<<endl;
}
main
#include <iostream>
#include "testing.h"
using namespace std;
using std::string;
int main()
{
testing tester;
tester.printname("JPR"); //error since testing::printname is inaccessible no idea
return 0;
}
If you don't specify the visibility of the members, they are private.
You can either use a struct (visibility is public):
struct testing
{
string Name;
void printname(string name);
};
or you can specify that printname is public:
class testing
{
public:
void printname(string name);
private:
string Name;
};
Try the following:
testing.h
#ifndef TESTING_H
#define TESTING_H
#include <string>
class testing
{
public:
// Better to pass the parameter as const reference to avoid performing a copy.
void printname(const std::string& name);
private:
std::string Name;
};
#endif
testing.cpp
#include <iostream>
#include "testing.h"
void testing::printname(const std::string& name)
{
Name = name;
std::cout << Name << std::endl;
}
main.cpp
#include "testing.h"
int main()
{
testing tester;
tester.printname("JPR");
return 0;
}
In C++:
A class defined with the keyword class has private access for its members and its base classes by default.
Add public: access modifier to your class defition, to mark method as public:
class testing
{
string Name;
public:
void printname(string name);
};
when you create a class, every member function and member variable is set in default as private, which means that they won't be accessible. To make your function public you need to change this in your code:
class testing
{
private: //is private in default, i add it for better readabilty
string Name;
public:
void printname(string name);
};
Worth to mention that you (almost) ALWAYS want to keep all member variables private!
(Beginner in OOP.)
I have a person class which stores the name of the person. In a derived class instance printer, I need that name so that I can do further tasks with it.
#include <iostream>
#include <string>
class Person{
public:
std::string name;
};
class Printer: public Person{
public:
void print(){
printf("%s", this->name.c_str());
}
};
int main() {
Person one;
one.name = "john";
Printer printer;
printer.print();
return 0;
}
What am I not doing to have printer see the data in one ? I'd be having several printer-like objects so storing "john" only once is the goal here.
You have made the member vars public but this is not the right approach for the OOP, the right one is to have them under private access specifier and use setters and getters.
Now to your mistakes:
You use void for main but with c++ you can only use int for it.
You use std::string as an argument for printf but it can't accept it. (I passed the c_string of the std::string to correct that).
You use an object, from the parent class, and give it a name then use another object, from the driven one, to print the name of the first one. (I used only one)
#include <iostream>
#include <string>
class Person{
public:
std::string name;
};
class Printer: public Person{
public:
void print(){
printf("%s",this-> name.c_str());
}
};
int main() {
Printer printer;
printer.name = "name";
printer.print();
}
After your comments, I have updated Printer class to do your inttent
#include <iostream>
#include <string>
class Person{
public:
std::string name;
};
class Printer{
public:
void print(const Person& person ){
printf("%s", person.name.c_str());
}
};
int main() {
Person one;
one.name = "name";
Printer printer;
printer.print(one);
}
I'm coding simple shop program in cpp. I have 3 classes: Shop, Client, Bucket. Shop is parent class for Bucket. Shop has vector of clients and every client has his own bucket.
I've got problem with #include's. I have to include Client.h in Shop.h so the Shop could see the vector of clients, but it seems I also have to include Bucket.h in Clinet.h for similar reason.
This generates a problem: Bucket is being included before Shop so I get 'Base Class Undefined' error.
How can I make this work?
Shop.h
#pragma once
#include <vector>
#include <string>
#include "functions.h"
#include "Client.h"
class Shop {
protected:
std::vector<int> quantities;
std::vector<std::string> products;
std::vector<float> prices;
private:
std::vector<Client*> clients;
int loggedClient;
public:
Shop();
~Shop();
int readProducts();
int loadClientsBase();
int checkLoginData(std::string log, std::string pass, int *logged);
int checkIfSameLogin(std::string log);
int addClient();
void login();
void logout();
int sell();
virtual void display();
void displayLoggedClient();
int saveHistory();
};
Client.h
#pragma once
#include "Bucket.h"
class Client
{
private:
float money=0.0;
Bucket bucket;
std::string login;
std::string password;
std::string description;
public:
Client();
~Client();
void addLoginData(std::string log, std::string pass, std::string desc, float mon);
std::string getLogin() { return login; };
std::string getPassword() { return password; };
std::string getDescription() { return description; };
float getMoney() { return money; };
void addLogin(std::string log);
void addPassword(std::string pass);
void addDescription(std::string desc);
void addMoney(float m);
void addToBucket(std::string prod, int quant, float price);
void displayBucket();
Bucket getBucket() { return bucket; };
friend std::ostream& operator<<(std::ostream& os, Client& client);
};
Bucket.h
#pragma once
#include <vector>
#include <string>
#include "Shop.h"
class Bucket : public Shop
{
public:
Bucket();
~Bucket();
void addProduct(std::string name, int amount, float price);
void deleteProduct();
void display();
std::string getProduct(int i);
int getQuantity(int i);
float getPrice(int i);
int getNumberOfProducts() { return products.size(); };
void clearBucket();
};
Bucket.h includes Shop.h which includes Client.h which includes Bucket.h... And so on forever and ever. This is a circular dependency.
Shop.h doesn't need to include Client.h, it only needs to forward declare the Client class:
#pragma once
#include <vector>
#include <string>
#include "functions.h"
// #include "Client.h"
class Client; // Forward declaration of the class, that's needed for pointers to it
class Shop {
...
};
The implementation of Shop needs the full definition of Client, so the Shop source file (Shop.cpp?) needs to include Client.h.
To solve the immediate issue, you'll need to forward declare Client class in Shop.h. However the class hierarchy you are building here is confusing to say the least, e.g. each Client owns a Shop, changing the class hierarchy to something more sensible should remove the problem altogether.
I have the header file
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
#endif
in which the command std::vector<Rule> setOfRules; gives the error that Rule was not yet declared.
Switching the order of the declarations of the two classes gives
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
#endif
but then I get the error that expected class-name before ‘{’ token for the line class Rule : public Category.
How do I solve this?
You can use a forward declaration for class Rule ( based on the first example ).
class Rule;
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
// class Rule definition here
Check here
You can forward declare class Rule:
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Rule; // <-- here
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
#endif
I have the base class Manager and the derived class Worker, the inheritance seem to work properly - I've created a new object of the derived class using it's default constructor and i can output properly.
but now I want to make an overloaded constructor for the derived class (Worker) and there seem to be a compilation error, I tired to look for an answer but I didn't found one.
why the compiles says that Worker doesn't have id, name and salary fields? I've created a derived class by the book and created ctors for it.
Manager header:
#include <string>
#ifndef MANAGER_H
#define MANAGER_H
class Manager
{
public:
Manager (); //ctor
Manager (std::string, std::string, float, int); //overloaded ctor
friend void display (Manager&); //friend function is declared
~Manager (); //dtor
protected:
std::string id;
std::string name;
float salary;
private:
int clearance;
};
Manager cpp:
#include <iostream>
#include "Manager.h"
#include "Worker.h"
Manager::Manager() //default ctor
{
id = "M000000";
name = "blank";
salary = 0;
clearance = 0;
}
Manager::Manager(std::string t_id, std::string t_name, float wage, int num): id (t_id), name (t_name), salary(wage), clearance (num)
{
//overloaded ctor
}
Manager::~Manager()
{
//dtor
}
Worker header:
#include <string>
#ifndef Worker_H
#define Worker_H
class Worker: public Manager
{
public:
Worker();
Worker (std::string, std::string, float, int);
~Worker();
friend void display (Worker&); //friend function is declared
protected:
int projects;
private:
};
#endif // Worker_H
Worker cpp:
#include <iostream>
#include "Manager.h"
#include "Worker.h"
Worker::Worker() //default ctor
{
id = "w000000";
name = " - ";
salary = 0;
projects = 0;
}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) : id (t_id), name (t_name), salary (wage), projects (num);
{
//ctor
}
Worker::~Worker()
{
//dtor
}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) : id (t_id), name (t_name), salary (wage), projects (num)
{
//ctor
}
here you initialize the members id,name, salary and clearance defined in base class. you need to pass it to the base class constructor for initialization. you cannot initialize them directly.
id, name and clearance are protected so you can access them in derived class but you cannot initialize them directly using initialization list. either you can initialize inside the constructor or make a call to base constructor in initialization list.
Worker::Worker(std::string t_id, std::string t_name, float wage, int num):Manager(t_id,t_name,wage,0), projects (num)
{
//ctor
}
Derived classes don't see private members of their base class. You have to delegate the constructor.
Your Worker constructors should be like:
Worker::Worker() : Manager("w000000", " - ", 0, 0) {}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) :
Manager(t_id, t_name, wage, num)
{
}