I'm trying to inherit the name,skeletonType, and numLegs from my base class to my derived class.
I have a base class named Invertebrates and derived class named Spider. I want to be able to use the private variables with the derived class from my base class. I keep getting a compiling error on line 47 and it says expected primary-expression before ','.
I'm trying to get my output to look like this:
Spider:Brown Recluse, number of legs = 8, skeleton type = EXOSKELETON
Could someone help me out and point me in the right direction please. Here is what I put together so far.
// invertebrates.h
// invertebrate specifications
#ifndef _INVERTEBRATE_H_
#define _INVERTEBRATE_H_
#include <iostream>
using namespace std;
enum Skeleton_Type { NONE, HYDROSTATIC, EXOSKELETON };
class Invertebrate {
private:
string name;
Skeleton_Type skeletonType;
int numLegs;
protected:
void setSkeletonType(Skeleton_Type skeletonType);
void setNumLegs(int numLegs);
public:
Invertebrate();
Invertebrate(string name, Skeleton_Type skeletonType, int numLegs);
string getName();
Skeleton_Type getSkeletonType();
int getNumLegs();
virtual void print() = 0;
};
class Spider : public Invertebrate {
private:
const string NAME_PREFIX = "Spider: ";
public:
Spider();
Spider(string name);
virtual void print();
};
#endif // _INVERTEBRATE_H_
**********************************************************************
//invertebrates.cpp
#include "invertebrate.h"
void Invertebrate::setSkeletonType(Skeleton_Type skeletonType)
{
this->skeletonType = skeletonType;
}
void Invertebrate::setNumLegs(int numLegs)
{
this->numLegs = numLegs;
}
Invertebrate::Invertebrate()
{
name = "noName";
skeletonType = NONE;
numLegs = 0;
}
Invertebrate::Invertebrate(string name, Skeleton_Type skeletonType, int numLegs)
{
this->name = name;
this->skeletonType = skeletonType;
this->numLegs = numLegs;
}
string Invertebrate::getName()
{
return this->name;
}
Skeleton_Type Invertebrate::getSkeletonType()
{
return this->skeletonType;
}
int Invertebrate::getNumLegs()
{
return this->numLegs;
}
Spider::Spider(string name):Invertebrate(name,EXOSKELETON,8)
{
name = Invertebrate::getName();
}
void Spider::print()
{
string strSkType = "";
if(this->getSkeletonType() == 0)
strSkType= "none";
else if(this->getSkeletonType() == 1)
strSkType= "Hydrostatic";
else if(this->getSkeletonType() == 2)
strSkType= "exoskeleton";
cout << this->NAME_PREFIX + getName();
cout << ", number of legs = " << this->getNumLegs() << ", skeleton type = " << strSkType << endl;
}
int main()
{
Spider *sp = new Spider("Brown Recluse");
sp->print();
return 0;
}
OUTPUT:
Here are the issues in your code :-
In .h file -
const string NAME_PREFIX = "Spider: ";
is not a valid way to initialize cont members - const should be initialized through constructor initializer list (till C++11).
Correct way in .cpp
Spider::Spider(string name):NAME_PREFIX(name),Invertebrate(name,EXOSKELETON,8)
{
name = NAME_PREFIX + Invertebrate::getName();
}
In the same constructor you have written name&, which is wrong, just pass name.
Spider::Spider(string
name):NAME_PREFIX(name),Invertebrate(name,EXOSKELETON,8)
I think I finally discovered what your line 47 is:
Spider::Spider(string name):Invertebrate(name&,EXOSKELETON,8)
{
name = NAME_PREFIX + Invertebrate::getName();
}
This function has two problems:
What is that & in name&? That is not valid syntax!
You cannot access this->name directly, because it is private in the base class. Instead here you are modifying the local name argument, and that does nothing useful.
You could make the base name public or protected. Or you could add a setName() protected function.
But in my opinion this member is ok being private and read-only. The solution would be to specify the proper name at construction time:
Spider::Spider(string name)
:Invertebrate(NAME_PREFIX + name, EXOSKELETON, 8)
{
}
Related
I am trying to make an object as a parameter for my add() function in this code:
class EnterInfo
{
protected:
string name;
int age;
string birthmonth;
public:
EnterInfo()
{
}
EnterInfo(string n, int a, string b)
{
name = n;
age = a;
birthmonth = b;
}
};
class CourseInfo
{
protected:
string title;
public:
CourseInfo()
{
}
CourseInfo(string t)
{
title = t;
}
void add()
{
}
};
int main()
{
EnterInfo s1;
CourseInfo c1;
s1 = EnterInfo("Sand", 20, "Jan");
c1 = CourseInfo(" x Records");
}
I want the add() function to gather all the data from the object "s1" and compact it into an array that I can access later. I could add, remove, or edit the data moving forward or even maybe make a new object "c2" which contains "y records" with the same s1 values ("sand", 20, "Jan"), however, I have no idea how to implement this in code.
c1.add(s1); // assume s1 (EnterInfo): Sand 20 Jan
c1.add(s2); // assume s2 (EnterInfo): Paul 23 Aug
this is the code I want to work with. I don't know how to make it work though. The end game would be this
c1.print();
output:
x records
Sand 20 Jan
Paul 23 Aug
create a vector of EnterInfo objects and put it in CourceInfo class. The code below does what you need:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class EnterInfo
{
public:
string name;
int age;
string birthmonth;
EnterInfo()
{
name = "";
age = 0;
birthmonth = "";
}
EnterInfo(string n, int a, string b)
{
name = n;
age = a;
birthmonth = b;
}
};
class CourseInfo
{
protected:
string title;
vector<EnterInfo> info_vec;
public:
CourseInfo()
{
title = "";
}
CourseInfo(string t)
{
title = t;
}
void add(const EnterInfo enterInfo)
{
this->info_vec.push_back(enterInfo);
}
void print() {
cout << this->title << endl;
for (const auto& it : this->info_vec) {
cout << it.name << " " << it.age << " " << it.birthmonth << endl;
}
}
};
int main()
{
EnterInfo s1("Sand", 20, "Jan");
EnterInfo s2("Arash", 21, "Feb");
CourseInfo c1(" x Records");
c1.add(s1);
c1.add(s2);
c1.print();
}
Side notes:
1- It's better to assign default values to the members of your class in the constructor.
2- I changed the access level of your EnterIndo members into public in order to use them in add function but the standard way is to set them to private and create getters and setters for them.
Research about std::vector and get/setters if you are not familiar with them.
[The code below is runnable so feel free to run it to see what I am talking about]
I am following along with a tutorial from a book that is Java-based. The code below is essentially a bunch of classes that can be used to accurately get the description and price of a beverage ordered (no matter how many additional condiments are added on to the base Beverage). The issue is the getDescription() and cost() functions in the Beverage class are not being overridden by the CondimentDecorator class, or any of the various condiment classes (Mocha, Milk, Whip, etc.).
When I run it, "Unknown Beverage" prints out as the description.
How can I figure out where the inheritance bug is at?
#include <iostream>
#include <string>
using namespace std;
class Beverage {
string description = "Unknown Description";
public:
string getDescription(){
return description;
}
int cost(); // just declare it - don't do anything
};
class HouseBlend : public Beverage {
string description = "House Blend";
string getDescription(){
return description;
}
int count(){
return .89;
}
};
class DarkRoast : public Beverage {
string description = "Dark Roast";
string getDescription(){
return description;
}
int count(){
return .99;
}
};
class Decaf : public Beverage {
string description = "Decaf";
string getDescription(){
return description;
}
int count(){
return 1.05;
}
};
class Espresso : public Beverage {
string description = "Espresso";
string getDescription(){
return description;
}
int count(){
return 1.99;
}
};
class CondimentDecorator : public Beverage {
string getDescription();
};
class Soy : public CondimentDecorator {
Beverage *beverage;
public:
Soy(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Soy ";
}
int cost(){
return beverage->cost() + .15;
}
};
class Milk : public CondimentDecorator{
Beverage *beverage;
public:
Milk(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Milk ";
}
int cost(){
return beverage->cost() + .10;
}
};
class Mocha : public CondimentDecorator{
Beverage *beverage;
public:
Mocha(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Mocha ";
}
int cost(){
return beverage->cost() + .20;
}
};
class Whip : public CondimentDecorator{
Beverage *beverage;
public:
Whip(Beverage *beverage){
this->beverage = beverage;
}
string getDescription(){
return beverage->getDescription() + " , Whip ";
}
int count(){
return beverage->cost() + .10;
}
};
//class StarbuzzCoffeeRun {
int main(){
Beverage *beverage = new Espresso;
cout << beverage->getDescription(); // << "$" << beverage->cost() << endl ;
Beverage *beverage2 = new DarkRoast;
beverage2 = new Mocha(beverage2);
cout << beverage2->getDescription();
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
cout << beverage2->getDescription(); // << "$" << beverage2->cost() << endl ;
Beverage *beverage3 = new HouseBlend;
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
cout << beverage3->getDescription(); // << "$" << beverage3->cost() << endl ;
return 0;
}
Couple of things wrong here.
The biggest one (causing the problem you're seeing) is that by doing something like this:
class HouseBlend : public Beverage {
string description = "House Blend";
// ...
};
What you're actually doing here is declaring a new member description, not setting Beverage's description.
To actually set Beverage's variable description, you will need to set it in a constructor or something:
class HouseBlend : public Beverage {
public:
HouseBlend () {
description = "House Blend";
}
};
Of course, if you want to access a parent's variable inside the child, it will have to be public or protected:
class Beverage {
protected:
string description = "Unknown Description";
public:
string getDescription(){
return description;
}
int cost(); // just declare it - don't do anything
};
Of course, you could set it in a setter too, but you you get the idea.
The other thing wrong here is with your count() function:
int cost(); // just declare it - don't do anything
There are 2 things wrong with this:
It needs to be virtual. If it's not, it will just end calling the base function and not the overloaded one when you create a pointer to it.
virtual int cost(); // so the compiler knows it will get overloaded at runtime
It needs to have an implementation. Even if the function does nothing, it still needs to have an "implementation" or else the compiler will complain.
virtual int cost() {return 0;} // Return some value that we know shouldn't exist
If you have a virtual function, you have the option of a pure virtual function which allows you to have no implementation, but override it in the child class:
virtual int cost() = 0; // This function has no implementation, but derived classes will give it one.
Note that this makes Beverage into a abstract class, and that comes with some restrictions for how you can use it. However, you seem to use it like an abstract class, so I'm guessing that this is what you were expecting anyway.
Edit
So, after I hit "post," I realized that technically I didn't answer your question which seems to be why getDescription() doesn't get overridden. The answer is similar to cost(), in that it needs to be virtual as well:
class Beverage {
string description = "Unknown Description";
public:
virtual string getDescription(){
return description;
}
virtual int cost() = 0;
};
This will technically allow getDescription() to get overridden when you use it in a pointer context. However, this isn't the best solution. It is probably better in the long run to make description protected instead.
Otherwise you're making a bunch of extra description variables you don't need. That will ultimately waste memory. And it makes your design clunkier. So just use protected instead.
I'm doing an assignment with virtual classes, I need to implement a pure virtual method which later will be implemented in an inherited class.
I solved a problem before with pure virtual methods which worked flawlessly, solving by myself the error i receive now ( error C2259: 'Playlist': cannot instantiate abstract class) - by implementing a method in an inherited class.
class Record
{
char* artist;
char* titlu;
int durata;
public:
Record()
{
artist = new char[50];
titlu = new char[50];
durata = 0;
}
void setArtist(char *s)
{
strcpy(artist, s);
}
char* getArtist()
{
return artist;
}
void setTitlu(char* s)
{
strcpy(titlu, s);
}
char* getTitlu()
{
return titlu;
}
void setDurata(int n)
{
int durata = n;
}
int getDurata()
{
return durata;
}
};
class Playlist
{
Record* p; /// "Record" is another class
public:
Playlist(int n)
{
p = new Record[n];
}
virtual void sortare(int n) = 0;
};
class PlaylistImplementation :public Playlist
{
public:
void sortare(int n)
{
if (n == 1)
{
cout << "1";
}
else if (n == 2)
{
cout << "2";
}
else
cout << "3";
}
};
Here is the main():
int main()
{
int n;
cout << "Number of tracks ?";
cin >> n;
Playlist x(n); /// I use VS 2019 and "x" has a red tilde underneath,
/// also error is at this line.
cin.ignore();
cin.get();
return 0;
}
I expect to instantiate an object from class Playlist.
You can't instantiate Playlist directly because it is abstract, so in main, instead of:
Playlist x(n);
you need
PlaylistImplementation x(n);
And you need a constructor in PlaylistImplementation like so:
PlaylistImplementation (int n) : PlayList (n) { }
Member 'p' of type Record in class Playlist is implicitly declared private. For access you need to add public member functions (e.g. to store data to a record).
I am new to c++ programming,I am trying to execute the following code but it
shows the error
no matching function for call to ‘Flower::Flower()’ Rose(string n =
"No flower", string c = "Red") : color(c) {}
even though i have given parametric constructor in my class Flower still it says no matching function call.
#include <iostream>
#include <string>
using namespace std;
class Flower
{
public:
string name;
Flower (string n):name (n)
{
}
void getFlowerName ()
{
cout << name << " " << "is" << " ";
}
};
class Rose:private Flower
{ // Inherit Flower as private
public:
string color;
/* Initialize name and color data members */
Rose (string n = "No flower", string c = "Red"):color (c)
{
}
void getFlowerName (Rose & r)
{
cout << r.color << endl;
}
// using Flower::getFlowerName ;// Allow call to getFlowerName() method in the base class
};
class Rose:private Flower
{ // Inherit Flower as private
public:
string color;
/* Initialize name and color data members */
Rose (string n = "No flower", string c = "Red"):color (c)
{
}
void getFlowerName (Rose & r)
{
cout << r.color << endl;
}
using Flower::getFlowerName; // Allow call to getFlowerName() method in
the base class
};
Derived classes should call base classes:
class Rose : private Flower
{
public:
std::string color;
Rose (const std::string& n = "No flower",
const std::string& c = "Red") : Flower(n), color(c)
{
}
// ...
};
As currently you call implicitly the default Flower's constructor, but it is not existent.
Create Flower::Flower() default constructor.
Flower(){ name = NULL; }
I am fairly new to C++ and I am wanting to understand why my program is giving me this error. I constructing a program that will simulate a colony of bunnies. Being able to automatically add them, give them names, ages, etc.
These are the errors that I am getting:
main2.cpp: In function ‘int main()’:
main2.cpp:109:6: error: ‘void Bunny::printBunny()’ is private
void printBunny()
^
main2.cpp:132:26: error: within this context
colony[ i ].printBunny();
^
Here is the code that I have come up with.
enter code here
#include <iostream>
#include <string>
#include <ctime>
#include <vector>
#include <cstdlib>
using namespace std;
void setSex( void );
char getSex();
void setColor( void );
string getColor();
void setAge( void );
int getAge();
void setName( void );
string getName();
void printBunny();
static const int POSSIBLE_NAMES = 5;
static const int POSSIBLE_COLORS = 4;
class Bunny
{
char sex;
string color;
int age;
string name;
bool radioactive_mutant_vampire_bunny;
BunnyData()
{
//srand( time( 0 ) );
setSex();
setColor();
setAge();
setName();
}
void setSex()
{
int randomNumber = 1 + rand() % 2;
( randomNumber == 1 ) ? sex = 'm' : sex = 'f';
}
char getSex()
{
return sex;
}
void setColor()
{
//color = possibleColors[ 0 + rand() % POSSIBLE_COLORS ];
}
string getColor()
{
return color;
}
void setAge()
{
age = 0;
}
int getAge()
{
return age;
}
void setName()
{
//name = possibleNames[ 0 + rand() % POSSIBLE_NAMES ];
}
string getName()
{
return name;
}
void printBunny()
{
cout << "Name: " << getName() << endl;
cout << "Sex: " << getSex() << endl;
cout << "Color: " << getColor() << endl;
cout << "Age: " << getAge() << endl;
}
};
int main()
{
vector< Bunny > colony;
cout << "Welcome to Bunny Graduation!" << endl << endl;
for( int i = 0; i < 5; ++i )
{
colony.push_back( Bunny() );
}
for( int i = 0; i < 5; ++i )
{
colony[ i ].printBunny();
cout << endl;
}
return 0;
}
Everything in a class has private access unless stated otherwise For example,
class access
{
int iAmPrivate; // private. Not accessible outside of the class
public:
int getValue() //public and accessible to all
{
return iAmPrivate;
}
int iAmPublic; //also public
}
Documentation on access levels.
You need to declare them to be public, if you don't, these members are private by default, which means you cannot invoke them outside the class.
class Bunny
{public:
void printBunny() {...}
};
You really need to consider which class access modifier you should apply to the member, because normally, we don't use just one type of access modifier in OO.
You can check this site to learn more about it.
In your class:
class Bunny
{
char sex;
string color;
int age;
string name;
// Rest of class fields ...
}
All the fields are private by default. This is because you have not used the keyword public: before you declare the fields of the class Bunny. As a result, you cannot invoke/call these fields and functions outside of the class, as you have tried in:
colony[ i ].printBunny(); // you are calling a private member of class Bunny outside of the class
There are 2 ways to get around this error:
One way is that you can declare the class members as public. This will allow the functions and fields to be invoked outside of the class:
class Bunny
{
public: // declare all fields of the class as public
char sex;
string color;
int age;
string name;
// Rest of class fields ...
}
Another thing you can do is declare Bunny as a struct instead if a class. This way, all your fields sill be accessible outside the struct:
struct Bunny
{
char sex;
string color;
int age;
string name;
// Rest of class fields ...
}