The question:
Why is the following error happening?
definition of implicity-declared 'Clothing::Clothing()
The context:
As an assignment I have to do constructors, destructors and methods in a class Clothing. I'm having a problem when I try to define the constructor in clothing.cpp. I have read that the problem is because I did not declare the constructor in clothing.h, but I think how I have done it, it's declared. I have no clue where the problem lies.
My code:
clothing.h:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing();
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
clothing.cpp:
#include <iostream>
#include "clothing.h"
#include <string>
#include <sstream>
using namespace std;
Clothing::Clothing() :
gender(1),
size(1),
name("outofstock") {
}
Clothing::Clothing(const Clothing& t) :
gender(t.gender),
size(t.size),
name(t.name) {
}
Clothing::Clothing(int gender, int size, string name) {
}
int Clothing::getGender() {
return gender;
}
int Clothing::getSize() {
return size;
}
string Clothing::getName() {
return name;
}
void Clothing::setGender(int gender1) {
gender = gender1;
}
void Clothing::setSize(int size1) {
size = size1;
}
void Clothing::setName(string name1) {
name = name1;
}
void Clothing::print() {
cout << name << " " << gender << " " << size << endl;
}
void Clothing::toString() {
stringstream ss;
ss << name << " " << gender << " " << size;
cout << ss.str();
}
Errors: \src\clothing.cpp:7:21: error: definition of implicitly-declared 'Clothing::Clothing()'
\src\clothing.cpp:14:37: error: definition of implicitly-declared 'Clothing::Clothing(const Clothing&)'
The error is: you declared a destructor but you didn't define it. Add a definition for the destructor or define it as default:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing() = default; // <-- add a default destructor
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
After fixing this your code snippet works: tio.run
If you have more problems with your code, the problems are outside of your provided code snippet.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'mm getting a bit confused why this isn't printing the name!
I've got a human.cpp :
#include <string>
#include <iostream>
#include "human.h"
human::human(int age, human *n){
m_age=age;
name = new char[2];
human::~human() = default;
void human::printDetails(){
std::cout <<"name is " << name << " age is " << m_age << std::endl;
}
and human.h:
class human {
public: //: needed
human(int age, human *name);
~human();
void printDetails();
private :
char *name;
int m_age;
};
and finally the main.cpp:
#include <iostream>
#include <string>
#include "human.h"
int main()
{
human *Alex = new human(10, Alex); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
}
So my issue is: it prints the age, but does not print the name? Any suggestions? Thanks :)
There is no need for any new in your code. Since you #included <string> in your code I assume you want to use it:
#include <string>
#include <iostream>
class Person
{
int age;
std::string name;
public:
Person(int age, std::string name)
: age { age },
name { name }
{}
int get_age() const { return age; }
std::string const& get_name() const { return name; }
void print_details() const {
std::cout << "My name is " << name << ". I am " << age << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you *really* want to do it the hard waytm:
#include <cstring> // std::strlen()
#include <utility> // std::exchange(), std::swap()
#include <iostream>
class Person
{
char *name_;
int age_;
public:
Person(int age, char const *name) // constructor
// we don't want to call std::strlen() on a nullptr
// instead allocate just one char and set it '\0'.
: name_ { new char[name ? std::strlen(name) + 1 : 1]{} },
age_ { age }
{
if (name)
std::strcpy(name_, name);
}
Person(Person const &other) // copy-constructor
: name_ { new char[std::strlen(other.name_) + 1] },
age_ { other.age_ }
{
std::strcpy(name_, other.name_);
}
Person(Person &&other) noexcept // move-constructor
: name_ { std::exchange(other.name_, nullptr) }, // since other will be
age_ { other.age_ } // wasted anyway, we
{} // "steal" its resource
Person& operator=(Person other) noexcept // copy-assignment operator
{ // since the parameter other got
std::swap(name_, other.name_); // copied and will be destructed
age_ = other.age_; // at the end of the function we
return *this; // can simply swap the pointers
} // - know as the copy&swap idiom.
~Person() { delete[] name_; } // destructor
void print_details() const
{
std::cout << "I am " << name_ << ". I am " << age_ << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you don't want to implement the special member functions you'd have to = delete; them so the compiler-generated versions - which won't work correctly for classes managing their own resources - won't get called by accident.
#include <iostream>
#include <cstring>
#include <new>
using namespace std;
class human {
public:
human(int age, const char * name)
{
m_age=age;
m_name = new char[strlen(name)+1];
strcpy(m_name,name);
}
~human()
{
delete[] m_name;
}
void printDetails()
{
std::cout <<"name is " << m_name << " age is " << m_age << std::endl;
}
private :
char *m_name;
int m_age;
};
int main()
{
human *Alex = new human(10, "alex"); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
delete Alex;
return 0;
}
You need to read more. The example you shared was wrong at many level, also read about dynamic memory management.
I guess you're confused with the second parameter of the human constructor. Look at this changes:
human.h
class human {
public:
human(int age, char *name);
human(const human& h);
human& operator=(const human& h);
void printDetails();
virtual ~human();
private:
int age;
char *name;
};
human.cpp
human::human(int _age, char *_name) {
age = _age;
name = new char[strlen(_name)+1];
strcpy(name, _name);
}
human::human(const human& _h) { //Copy constructor
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
}
human& human::operator=(const human& _h) { //Copy assignment operator
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
return *this;
}
void human::printDetails(){
std::cout <<"name is " << name << " age is " << age << std::endl;
}
human::~human() { //Destructor
delete[] name;
}
main.cpp
int main() {
human *alex = new human(10, "Alex");
alex->printDetails();
human *anotherAlex = new human(*alex);
anotherAlex->printDetails();
delete alex;
delete anotherAlex;
}
A suggestions: I would use Human as the class names and alex for the variable names. (See how I capitalized them)
For beginner you may use std::string, so you already included it. ))
human.h
#include <string>
class human
{
public: //: needed
human(int age, std::string name);
void printDetails();
private :
std::string name;
int m_age;
};
human.cpp
#include <iostream>
#include "human.h"
human::human(int age, std::string n)
{
m_age = age;
name = n;
}
void human::printDetails()
{
std::cout <<"name is: " << name << " age is: " << m_age << std::endl;
}
main.cpp
#include "human.h"
int main()
{
human *Alex = new human(10, "Alex");
Alex->printDetails();
}
I am making a c++ program to store employee's data like name, id, saleamount, commission amount and calculate earning (sales*commission). I am using the concept of inheritance. My base class is 'Employee' and my derived class is 'SeniorEmployee'. When I run the program, the compiler gives me an error that I cannot access the private members of base class. The errors are like this
error: 'std::__cxx11::string Employee::name' is private.
Another error on 2nd line is
error: 'int Employee::id' is private
Again the same error on 3rd line
error: 'double Employee::sales' is private
Following is my code. I have included all files.
File Employee.h
#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_
#include <iostream>
#include <string>
using namespace std;
class Employee {
public:
Employee(string EmpName, int EmpID, double EmpSales, double EmpComm);
void setName(string EmpName);
string getName();
void setID(int EmpID);
int getID();
void setSales(double EmpSales);
double getSales();
void setComm(double EmpComm);
double getComm();
double earning();
private:
string name;
int id;
double sales;
double commission;
};
#endif
File Employee.cpp
#include <iostream>
#include <string>
#include "Employee.h"
using namespace std;
Employee::Employee(string EmpName, int EmpID, double EmpSales, double EmpComm): name(EmpName), id(EmpID), sales(EmpSales), commission(EmpComm)
{
}
void Employee::setName(string EmpName) {
name=EmpName;
}
string Employee::getName() {
return name;
}
void Employee::setID(int EmpID) {
id=EmpID;
}
int Employee::getID() {
return id;
}
void Employee::setSales(double EmpSales) {
sales=EmpSales;
}
double Employee::getSales() {
return sales;
}
void Employee::setComm(double EmpComm) {
commission=EmpComm;
}
double Employee::getComm() {
return commission;
}
double Employee::earning() {
return sales*commission;
}
File SeniorEmployee.h
#ifndef SENIOREMPLOYEE_H_
#define SENIOREMPLOYEE_H_
#include "Employee.h"
#include <iostream>
#include <string>
using namespace std;
class SeniorEmployee: public Employee {
public:
SeniorEmployee(string EmpName, int EmpID, double EmpSales, double EmpComm, double BaseSalary);
void setBaseSalary(double BaseSalary);
double getBaseSalary();
private:
double bsalary;
};
#endif
File SeniorEmployee.cpp
#include <iostream>
#include <string>
#include "SeniorEmployee.h"
using namespace std;
SeniorEmployee::SeniorEmployee(string EmpName, int EmpID, double EmpSales, double EmpComm, double BaseSalary) : Employee(name,id,sales,commission)
{
}
void SeniorEmployee::setBaseSalary(double BaseSalary) {
bsalary=BaseSalary;
}
double SeniorEmployee::getBaseSalary() {
return bsalary;
}
File main.cpp
#include <iostream>
#include "SeniorEmployee.h"
using namespace std;
int main() {
string empname = "Fareed Shuja";
int empid = 3978;
double empsales = 30.0;
double empcomm = 0.99;
double basesalary = 50.0;
SeniorEmployee emp(empname,empid,empsales,empcomm,basesalary);
cout << "Name of the Employee is : " << emp.getName() << endl;
cout << "Employee ID is : " << emp.getID() << endl;
cout << "Sale Amount is : " << emp.getSales() << endl;
cout << "Commission is : " << emp.getComm() << endl;
cout << "Earning is : " << emp.earning() << endl;
cout << "Employee's base salary is " << emp.getBaseSalary() << endl;
return 0;
}
The following line in SeniorEmployee.cpp is incorrect:
SeniorEmployee::SeniorEmployee(string EmpName, int EmpID, double EmpSales, double EmpComm, double BaseSalary) : Employee(name,id,sales,commission)
It's attempting to access the private variables 'name', 'id', etc... instead of passing your constructor's arguments to the base class constructor. It should instead be:
SeniorEmployee::SeniorEmployee(string EmpName, int EmpID, double EmpSales, double EmpComm, double BaseSalary) : Employee(EmpName,EmpID,EmpSales,EmpComm)
Also if you want to access variables from a derived class but not make them visible outside of the class they must be declared protected instead of private.
I'm trying to write a program that takes the grades and prints out the following:
ID:123 NAME:John GRADE:78
but instead I'm getting:
ID:-842150451 NAME: GRADE: 78
Can you guys help me and give me some extra tips to make my code cleaner since I'm fairly new to C++.
Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
Student(int num, string text);
int getID();
void setExamGrade(int a, int b);
int getOverallGrade();
void display();
string getName();
string name;
int id;
int exams[3];
int sum;
int average;
};
#endif
Student.cpp
#ifndef STUDENT_CPP
#define STUDENT_CPP
#include "Student.h"
#include <iostream>
#include <string>
using namespace std;
Student::Student(int num, string text)
{
num = id;
text = name;
exams[0, 1, 2] = 0;
}
int Student::getID() {
return id;
}
string Student::getName() {
return name;
}
void Student::setExamGrade(int a, int b) {
exams[a] = b;
}
int Student::getOverallGrade() {
sum = exams[0] + exams[1] + exams[2];
average = sum / 3;
return average;
}
void Student::display() {
cout << "ID: " << getID();
cout << " NAME: " << getName();
cout << " GRADE: " << getOverallGrade() << endl;
}
#endif
gradebook.cpp
#ifndef GRADEBOOK_CPP
#define GRADEBOOK_CPP
#include "Student.h"
#include <iostream>
using namespace std;
int main() {
Student *s = new Student(123, "John");
s->setExamGrade(0, 80);
s->setExamGrade(1, 60);
s->setExamGrade(2, 95);
s->display();
delete s;
return 0;
}
#endif
You never assign to id in the constructor, hence it's uninitialized and you will have undefined behavior when you print it.
Change
num = id;
to
id = num;
Same with the name.
Also, the statement
exams[0, 1, 2] = 0;
doesn't do what you expect it to do, it only initializes exams[2] to sero, and leaves the rest uninitialized. The expression 0, 1, 2 uses the comma operator.
Either assign to all members of the array separately, or use a constructor member initializer list (which I recommend for all the initialization).
I'm having a little problem when trying to compile a very simple test c++ code:
I have a Warrior class when I want to define a copy constructor for test purposes. I declare it in Warrior.h and define it in Warrior.cpp.
When compiling the code with g++ on Ubuntu, it works great, however when trying to compile it on Windows7 Codeblocks (mingw), I get the following message :
error: definition of implicitly-declared 'Warrior::Warrior(const Warrior&)'|||=== Build failed: 1 error(s)
The code:
Warrior.h
#ifndef WARRIOR_H_INCLUDED
#define WARRIOR_H_INCLUDED
#include <string>
#include "Arme.h"
#include "Warrior.h"
class Warrior{
public:
Warrior(Warrior const& other);
std::string getName() const;
Warrior setName(std::string name);
int getAge() const;
Warrior setAge(int age);
int getLife() const;
Warrior setLife(int life);
Arme getArme() const;
Warrior setArme(Arme& arme);
void attaquer(Warrior& autreCombattant);
bool isAlive() const;
Warrior setIsAlive(bool isAlive);
Warrior(std::string name, int age);
~Warrior();
private:
std::string m_name;
int m_age;
int m_life;
bool m_isAlive;
Arme m_arme;
};
#endif // WARRIOR_H_INCLUDED
Warrior.cpp
#include "Warrior.h"
#include "Arme.h"
#include <iostream>
#include <string>
using namespace std;
Warrior Warrior::setName(string name){
m_name=name;
return *this;
}
string Warrior::getName() const{
return m_name;
}
int Warrior::getAge() const{
return m_age;
}
Warrior Warrior::setAge(int age){
m_age=age;
return *this;
}
int Warrior::getLife() const{
return m_life;
}
Warrior Warrior::setLife(int life){
m_life=life;
if(life<=0){
cout << m_name << " est mort." << endl;
}else{
cout << m_name << " a la vie suivante : " << m_life << endl;
}
return *this;
}
Arme Warrior::getArme() const{
return m_arme;
}
Warrior Warrior::setArme(Arme& arme){
m_arme=arme;
cout << m_name << " a maintenant l'arme suivante : " << arme.getName() << endl;
return *this;
}
void Warrior::attaquer(Warrior& autreCombattant){
autreCombattant.setLife(autreCombattant.getLife() - m_arme.getDegat());
}
bool Warrior::isAlive() const{
return m_isAlive;
}
Warrior Warrior::setIsAlive(bool isAlive){
m_isAlive=isAlive;
return *this;
}
Warrior::Warrior(string name, int age): m_name(name), m_age(age), m_arme("b",4){
m_life=300;
cout << name << " vient de rejoindre l'arene" << endl;
}
Warrior::~Warrior(){}
Warrior::Warrior(Warrior const& autre): m_name(autre.getName())
{}
Arme.h
#ifndef ARME_H_INCLUDED
#define ARME_H_INCLUDED
#include <string>
class Arme{
private:
int m_degat;
std::string m_name;
public:
int getDegat() const;
Arme setDegat(int degat);
std::string getName() const;
Arme setName(std::string name);
Arme(std::string name, int degat);
Arme();
};
#endif // ARME_H_INCLUDED
Arme.cpp
#include "Arme.h"
#include <iostream>
#include <string>
using namespace std;
int Arme::getDegat() const{
return m_degat;
}
Arme Arme::setDegat(int degat){
m_degat=degat;
return *this;
}
string Arme::getName() const{
return m_name;
}
Arme Arme::setName(string name){
m_name=name;
return *this;
}
Arme::Arme(std::string name, int degat): m_name(name), m_degat(degat){
}
Arme::Arme(){
m_name="default weapon";
m_degat=1;
}
Thanks for your help
I have removed my project on codeblocks, then created a new one and I have added the previously created files, now it compiles without any problem.
It seems to me Codeblocks has a kind of cache engine that was not refreshed...weird!
// main.cpp
#include <iostream>
#include <vector>
#include <string>
#include "Student.h"
using namespace std;
void fillVector(vector<Student>&);
void printVector(const vector<Student>&);
int main()
{
vector<Student> myClass;
fillVector(myClass);
printVector(myClass);
return 0;
}
void fillVector(vector<Student>& newMyClass)
{
string name;
char grade;
cout << "How many you students are in your class? ";
int classSize;
cin >> classSize;
for (int i=0; i<classSize; i++)
{
cout<<"Enter student name: ";
cin>>name;
cout<<"Enter student grade: ";
cin>>grade;
Student newStudent(name, grade);
newMyClass.push_back(newStudent);
cout<<endl;
}
cout<<endl;
}
void printVector(const vector<Student>& newMyClass)
{
int size = newMyClass.size();
for ( int i=0; i<size; i++ )
{
cout<<"Student name: "<<newMyClass[i].getName()<<endl;
cout<<"Student grade: "<<newMyClass[i].getGrade()<<endl;
cout<<endl;
}
}
// Student.h
#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student();
Student(string, char);
~Student();
string getName() const;
char getGrade() const;
void setName(string);
void setGrade(char);
private:
string newName;
char newGrade;
};
#endif // STUDENT_H_INCLUDED
// Student.cpp
#include "Student.h"
Student::Student()
{
newGrade = ' ';
}
Student::Student(string name, char grade)
{
newName = name;
newGrade = grade;
}
Student::~Student() {}
string Student::getName() const
{
return newName;
}
char Student::getGrade() const
{
return newGrade;
}
void Student::setName(string name)
{
newName = name;
}
void Student::setGrade(char grade)
{
newGrade = grade;
}
My aim is to declare a class called CreateGradeBook inside Student.hand define it in Student.cpp and put all the code of the main.cpp in it. In other words I want main.cpp to be still there but with no codes in it like below;
#include <iostream>
using namespace std;
int main()
{
}
Please be tolerant if my question is inappropriate or off topic as I'm fairly new with StackOverflow. I've read FAQ section but not all of it.
Well here's a start
class CreateGradeBook
{
public:
void fillVector();
void printVector() const;
private:
vector<Student> myClass;
};
Notice how the vector you declared in main has become a private data member myClass. The two functions you declared have become public methods of CreateGradeBook. Notice also that they have lost their parameters instead they'll now operate on the private data member myClass.
I'll leave you to do the rest.