new to c++ and cant figure out why visual studio doesn't like my "HealthProfile person.setFirstName(first)" line of code. The error is with "person" and the error is no default constructor. It's probably something painfully obvious, but my code is almost identical from the code in my book. Thanks in advance!
main:
#include <iostream>
#include "HealthProfile.h"
using namespace std;
int main()
{
string first;
HealthProfile person;
cout << "Enter first name" << endl;
getline(cin,first);
person.setFirstName(first);
}
header:
#include <string>
using namespace std;
class HealthProfile
{
public:
HealthProfile(string, string, string, int, int, int, int, int);
void setFirstName(string);
string getFirstName();
void setLastName(string);
string getLastName();
};
function:
#include <iostream>
#include "HealthProfile.h"
using namespace std;
HealthProfile::HealthProfile(string first, string last, string g,
int m, int d, int y, int h, int w)
{
setFirstName(first);
setLastName(last);
setGender(g);
setMonth(m);
setDay(d);
setYear(y);
setHeight(h);
setWeight(w);
}
void HealthProfile::setFirstName(string first)
{
firstName = first;
}
string HealthProfile::getFirstName()
{
return firstName;
}
void HealthProfile::setLastName(string last)
{
lastName = last;
}
string HealthProfile::getLastName()
{
return lastName;
}
There is nothing wrong with setFirstName().
The issue is that you've declared a constructor that takes three strings and five ints, this removes the default constructor which you are using when you call HealthProfile person
The solution is to either use the HealthProfile cosntructor and pass it three strings and five ints, or to declare and define a constructor that takes no parameters by adding HealthProfile(){} to the header.
This line in main:
HealthProfile person;
Declares an instance of the HealthProfile class using a default constructor. You've not declared a default constructor. Creating your own custom constructor prevents a default constructor from being implicitly created for you. If you want to use a default constructor as well as a custom one, you need to explicitly declare and define it. If you don't want to use a default constructor, then pass in arguments to use your custom one.
To declare a default constructor in your .h:
HealthProfile();
And to define it in your .cpp:
HealthProfile::HealthProfile() { }
Or to simply call your existing custom constructor in main:
HealthProfile person(first,last,g,m,d,y,h,w); // AFTER collecting values for these arguments
Related
I have been looking in different threads with this error which is quite common but it feels like the IDE I am using messed with my workspace and I can't quite find the problem. I am setting up an extremely basic class called "Movie" that is specified below:
Movie.hpp :
#ifndef MOVIE_HPP
#define MOVIE_HPP
#include <iostream>
#include <string>
using std::string, std::cout,std::size_t;
class Movie
{
private:
std::string name;
std::string rating;
int watched_ctr;
public:
Movie(const string& name, const string& rating, int watched_ctr);
~Movie();
//getters
string get_name() const;
string get_rating() const;
int get_watched() const;
//setters
void set_name(string name);
void set_rating(string rating);
void set_watched(int watched_ctr);
};
#endif // MOVIE_HPP
Movie.cpp:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
Movie::Movie(const string& name, const string& rating, int watched_ctr)
: name(name) , rating(rating) , watched_ctr(watched_ctr) {
}
Movie::~Movie()
{
cout << "Destructor for Movies class called /n";
}
//Getters
string Movie::get_name(){return name;}
string Movie::get_rating(){return rating;}
string Movie::get_watched(){return watched_ctr;}
//Setters
void Movie::set_name(std::string n){this -> name = n;}
void Movie::set_rating(std::string rating){this -> rating = rating;}
void Movie::set_watched(int ctr){this -> watched_ctr = ctr;}
The main.cpp I am trying only consists in creating one Movie object:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
int main()
{
Movie StarTrek("Star Trek", "G", 20);
}
As you can see, I set all the attribute to private in order to exercise with the set/get methods but I keep stumbling upon the same error on each of them stating >"C:/Users/.../ProjectsAndTests/MoviesClass/Movie.cpp:18:8: error: no declaration matches 'std::__cxx11::string Movie::get_name()"
if you could give me a hint on what might cause this error I would greatly appreciate thank you!
I tried opening another workspace with classes implemented inside of them and the syntax I am using is very close from this test workspace I opened which compiled fine (no error regarding declaration match).
There are 2 problems with your code.
First while defining the member functions outside class you're not using the const. So to solve this problem we must use const when defining the member function outside the class.
Second, the member function Movie::get_watched() is declared with the return type of string but while defining that member function you're using the return type int. To solve this, change the return type while defining the member function to match the return type in the declaration.
//----------------------vvvvv--------->added const
string Movie::get_name()const
{
return name;
}
string Movie::get_rating()const
{
return rating;
}
vvv------------------------------>changed return type to int
int Movie::get_watched()const
{
return watched_ctr;
}
Working demo
I've been trying to learn about parametrised constructors:
Here is the program I wrote:
#include <iostream> //Using a parametrised constructor i.e. we give an integer value as a parameter
using namespace std;
class item{
int cost;
int price;
public:
item (int a){
cost=a;
}
void display(){ //Display is not a constructor, hence we need to specify its return type and parameters
cout << cost;
}
} item1;
int main(){
item1(5);
item1.display();
return 0;
}
However, I get an error on Visual Studio Code:
call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type
Can anyone tell me what's wrong with the code?
At the end of class creation you are asking to create an object named item1 but you are not providing any value, that's why it is throwing error you cannot create an object without '('.
After object creation you can't call the constructor. you can access all the methods and fields.
#include <iostream> //Using a parametrised constructor i.e. we give an integer value as a parameter
using namespace std;
class item{
int cost;
int price;
public:
item (int a){
cost=a;
}
void display(){ //Display is not a constructor, hence we need to specify its return type and parameters
cout << cost;
}
} item1(5);
int main(){
item1.display();
return 0;
}
For some reason whenever I try running my code it always call the default constructor but it should be calling the constructor with parameters.
#include "pokemon.h"
int main()
{
int choice;
cout<<"input 1 2 or 3"<<endl;
cin>>choice;
if(choice==1||choice==2||choice==3)
{
pokemon(choice);
}
}
in my headerfile i have
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
using namespace std;
class pokemon{
public:
pokemon();//default constructor
pokemon(int a);
~pokemon();//desconstructor
pokemon(const pokemon& c);
void train();
void feed();
bool isnothappy();
string getName();//accessor for the name
int getPowerlevel();//accessor for the power level
string getColor();//accessor for the color
string getType();//accessor
int getHappylevel();//accessor
static int getNumObjects();
void set_type(string);//mutator
void set_color(string);//mutator
void set_power_level(int);//mutator
void set_happy_level(int);//mutator
void set_name(string);//mutator
private:
string name;
string color;
string type;
int power_level;
int happy_level;
static int numberobject;
};
and in my other .cpp file i have
int pokemon::numberobject=0;//initialize static member variable
pokemon::pokemon(){//default constructor
name="pikachu";
color="yellow";
type="electric";
power_level=0;
happy_level=1;
cout<<"The default constructor is being called"<<endl;
++numberobject;
}
pokemon::pokemon(int a)
{
if(a==0)
{
name="Pikachu";
color="yellow";
type="electric";
power_level=1;
happy_level=1;
}
else if(a==1)
{
name="Bulbasaur";
color="green";
type="grass";
power_level=1;
happy_level=1;
}
else if(a==2)
{
name="Charmander";
color="red";
type="fire";
power_level=1;
happy_level=1;
}
else if(a==3)
{
name="Squritle";
color="blue";
type="water";
power_level=1;
happy_level=1;
}
cout<<"Congratulations you have chosen "<<getName()<<". This " <<getColor()<<" "<<getType()<<" pokemon is really quite energetic!"<<endl;
++numberobject;
}
pokemon::~pokemon()
{
//cout<<"the destructor is now being called"<<endl;
//cout<<"the number of objects before the destructor is "<<pokemon::getNumObjects()<<endl;
--numberobject;
cout<<"Now you have a total number of "<<pokemon::getNumObjects()<<endl;
}
pokemon::pokemon(const pokemon& c)//copy constructor
{
name=c.name;
color=c.color;
type=c.type;
power_level=c.power_level;
happy_level=c.happy_level;
++numberobject;
}
I have both my constructors declared and defined in my other files but this darn thing always calls the default constructor
This code:
pokemon(choice);
means the same as:
pokemon choice;
It declares a variable called choice of type pokemon, and there are no arguments given to the constructor. (You're allowed to put extra parentheses in declarations in some places).
If you meant to declare a variable where choice is a constructor argument then you have to write:
pokemon foo(choice);
If you meant to create a temporary object (which will be immediately destroyed) with choice as argument, you can write (pokemon)choice;, or pokemon(+choice);, or since C++11, pokemon{choice};.
This issue with ambiguity between declarations and non-declarations can arise any time a statement begins with a type-name followed by (. The rule is that if it is syntactically correct for a declaration then it is treated as a declaration. See most-vexing-parse for other such cases.
I am learning C++ through TheNewBostons tutorials and there is one of the programs that I can't figure out how it works. I'll show you the codde before the question.
Main.cpp:
#include <iostream>
#include "People.h"
#include "Birthday.h"
using namespace std;
int main()
{
Birthday birthObject(12,28,1986);
People Ob("Vidar", birthObject);
Ob.printInfo();
}
Birthday.h:
#ifndef BIRTHDAY_H
#define BIRTHDAY_H
class Birthday
{
public:
Birthday(int m,int d,int y);
void prinDate();
private:
int month, day, year;
};
#endif
Birthday.cpp:
#include <iostream>
#include "Birthday.h"
using namespace std;
Birthday::Birthday(int m,int d,int y)
{
month = m;
day = d;
year = y;
}
void Birthday::prinDate()
{
cout << day << "/" << month << "-" << year << endl;
}
People.h:
#ifndef PEOPLE_H
#define PEOPLE_H
#include <string>
#include "Birthday.h"
using namespace std;
class People
{
public:
People(string x, Birthday bo);
void printInfo();
private:
string name;
Birthday dateOfBirth;
};
#endif
People.cpp:
#include "People.h"
#include "Birthday.h"
#include <iostream>
#include <string>
using namespace std;
People::People(string x, Birthday bo)
: name(x), dateOfBirth(bo)
{
}
void People::printInfo()
{
cout << name << " was born on ";
dateOfBirth.prinDate();
}
The thing that I can't figure out is how the objects are used as variables and parameters, and also how you can create an object without calling the constructor (in People.h).
A reasonable question.
What is happening here is that it is calling the copy constructor.
Whenever you declare a class there are several functions which are declared for you, unless you explicitly override them.
Default constructor (if no other constructor is explicitly declared)
Copy constructor if no move constructor or move assignment operator
is explicitly declared. If a destructor is declared generation of a
copy constructor is deprecated.
Move constructor if no copy
constructor, move assignment operator or destructor is explicitly
declared.
Copy assignment operator if no move constructor or move
assignment operator is explicitly declared. If a destructor is
declared generation of a copy assignment operator is deprecated.
Move
assignment operator if no copy constructor, copy assignment operator
or destructor is explicitly declared.
Destructor
Have a look here: http://en.wikipedia.org/wiki/Special_member_functions
In this case the copy constructor is called.
This expression (mem initializer)
dateOfBirth(bo)
in the constructor definition
People::People(string x, Birthday bo)
: name(x), dateOfBirth(bo)
{
}
means a call of the copy constructor of class Birthday to construct object dateOfBirth from object bo.
For example if you would add an explicitly defined copy constructor for class Birthday the following way
class Birthday
{
public:
Birthday(int m,int d,int y);
Birthday( const Birthday &rhs )
{
std::cout << "Birthday::Birthday( const Birthday & ) is called" << std::endl;
month = rhs.month; day = rhs.day; year = rhs.year;
}
void prinDate();
private:
int month, day, year;
};
then when this statement was executed
People Ob("Vidar", birthObject);
you would get message
Birthday::Birthday( const Birthday & ) is called
If you do not define explicitly the copy constructor then the compiler defines it implicitly.
Let's take this step by step:
Birthday birthObject(12,28,1986);
here you're creating a new local variable birthObject of type of Birthday class, passing as parameters (12,289,1986). That invokes the three-parameter constructor of Birthday class
People Ob("Vidar", birthObject);
Here you're creating a local variable Obof type People (note common conventions have class names starting with uppercase, variables starting with lowercase) and passing as parameters ("Vidar" and birthObject).
That invokes the two-parameters constructor of People. This is defined as:
People::People(string x, Birthday bo): name(x), dateOfBirth(bo) { }
Some notes here:
Both parameters are passed by value. This means that the copy constructor (implicit, because you haven't defined any) will be invoked for each of them. (note, as it has been noted in other answers, it is probably best to use const & instead).
attributes are initialized (name, dateOfBirth) (this involves an additional copy constructor for each of them).
Ob.printInfo();
Finally, the printInfo() method of the Ob instance is invoked... which in turn invokes the prinData() method of the Ob's attribute dateOfBirth. Those methods do not have parameters and are invoked on the respective instances.
I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:
class test
{
private:
char name[40];
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test()
{
char name [] = "Standard";
}
int main()
{ test *test1 = new test;
test1->display();
}
And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(
If there are no particular reasons to not use std::string, do use std::string.
But if you really need to initialize that character array member, then:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;
class test
{
private:
char name[40];
int x;
public:
test();
void display() const
{
std::cout<<name<<std::endl;
}
};
test::test()
{
static char const nameData[] = "Standard";
assert( strlen( nameData ) < sizeof( name ) );
strcpy( name, nameData );
}
int main()
{
test().display();
}
Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.
If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.
Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).
Also, you forgot to delete the test1 instance.
#include <iostream>
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
}
};
test::test()
{
name = "Standard";
}
int main()
{
test test1;
test1.display();
std::cin>>x;
}
Considering you tagged the question as C++, you should use std::string:
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test() : name("Standard")
{
}
c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.
Example of declaration line initialization:
class test1 {
char name[40] = "Standard";
public:
void display() { cout << name << endl; }
};
Example of constructor initialization:
class test2 {
char name[40];
public:
test2() : name("Standard") {};
void display() { cout << name << endl; }
};
You can see a live example of both of these here: http://ideone.com/zC8We9
My personal preference is to use the declaration line initialization because:
Where no other variables must be constructed this allows the generated default constructor to be used
Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists
Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:
Making the member const
Using a char* (this won't work if the member will hold anything but a literal string)
In the general case std::string should be preferred