Constructor setting all values to 0 - c++

So from an assignment I have from school, I have to make a default constructor that is supposed to set all floats and ints to 0 and all strings to "NA".
Earlier it was pretty easy I had to just do a constructor to set volume to 0, calories to 0 and etc.
My question is,
How does the syntax for setting all floats, and ints to 0 and trying to get strings to all say "NA"?
This is what I had so far
class Candy {
private:
float sweetness;
protected:
string color;
//CONSTRUCTOR//
void setName(string n);
void setFloat(float f);
void setInt(int i);
This is on another cpp file we have to do.
Candy::Candy() {
Candy(string n) {
setName(n);
}
Candy bo("NA");
}
Am I in the right direction? I am really new to this, and I am not very good with syntax. Thanks!

Use the constructors initialization list:
class Candy {
private:
float sweetness;
protected:
string color;
public:
Candy() : sweetness(0.0f), color("NA") { }
};
Or (in C++11 or later), use in-class initializers:
class Candy {
private:
float sweetness = 0.0f;
protected:
string color = "NA";
public:
Candy() = default;
};

Ok lets see your header file:
class Candy {
public:
Candy();
private:
float sweetness;
protected:
string color;
void setName(string n);
void setFloat(float f);
void setInt(int i);
};
You need to declare the constructor in the public section, so you can call it from outside. It has no return type and takes no parameters (it should set everything to 0 on its own and not values you provide it).
In the cpp-file you implement the constructor and the other methods you declared before:
#include "Candy.h" // Or whatever the filename is
Candy::Candy() {
sweetness = 0.0f;
color = "NA";
}
// Implement the other methods, I don't know what they should do
// Example:
void Candy::setName(string n) {
// Do what you want
}
Note you have to implement every method otherwise you will get errors.

Related

Initializing object to an empty list from a reference parameter

class ListOfGifts
{
private:
Gift list[50];
int count = 0;
public:
void suggest(ListOfGifts& affordable, float dollarLimit) const
{
// how do I initialize affordable to an empty list without a constructor
}
}
Trying to initialize a list from a parameter that is a reference. How can I do this?
Use an std::array:
class ListOfGifts
{
private:
std::array<Gift, 50> list;
int count = 0;
public:
void suggest(ListOfGifts& affordable, float dollarLimit) const
{
affordable.list = std::array<Gift, 50>{};
}
}
FYI, C++ is literally built on constructors. They will come up eventually, and they're actually quite helpful.

Inheritance, defining a function for creating an object of a specified type?

Title does not help im sure.
Anyway, at the moment i'm working with the following
http://puu.sh/7wJed.png
Everything's fine and inherited correctly, however, in order to create an object of say 'aircraftCarrier' i'd need to pass the 12 values + the two inherited values every-time i want to use a function such as
generateAirCraftCarrier(1,2,3,4,5,6,7,8,9,10,11,12);
I could simply pass in a navalVessel instance into the function instead, such that
generateAirCraftCarrier(myNavalVessel, inherit var 1, inherit var 2);
BUT this would not be entirely a solution because what happens when the aircraft carrier has a different 'Speed' for example?
can i have option parameters, which if null use the myNavalVessel object? Looking for some guidance here, sorry about the gibberish.
Why do you need one function to define all 12 values on an AircraftCarrier? Why not build it up with a number of setters on AircraftCarrier and NavalVessel? e.g:
class NavalVessel {
float speed_;
public:
void setSpeed(float speed) { speed_ = speed; }
};
class AircraftCarrier : public NavalVessel {
int noHeliPads_;
int noRunways_;
public:
void setNoHeliPads(int noHeliPads) { noHeliPads_ = noHeliPads; }
void setNoRunways(int noRunways) { noRunways_ = noRunways; }
};
int main() {
AircraftCarrier aircraftCarrier;
aircraftCarrier.setSpeed(25.3);
aircraftCarrier.setNoHeliPads(3);
aircraftCarrier.setNoRunways(2);
}
Could named parameters idiom be useful for you?
class AircraftCarrierParameters;
class AircraftCarrier
{
private:
AircraftCarrierParameters _params;
public:
AircraftCarrier(const AircraftCarrierParameters& params)
: _params(params) {}
AircraftCarrierParameters params() const { return _params;}
};
class AircraftCarrierParameters
{
private:
double _speed;
int _someOtherStuff;
public:
AircraftCarrierParameters()
: _speed(0) //default parameters
, _someOtherStuff(0)
{
}
double speed() const { return _speed; }
double someOtherStuff() const { return _someOtherStuff; }
AircraftCarrierParameters& setSpeed(double speed) { _speed = speed; return *this; }
AircraftCarrierParameters& setSomeOtherStuff(double stuff) { _someOtherStuff = stuff; return *this; }
};
AirCraftCarrier generateAirCraftCarrier(const AircraftCarrierParameters& params)
{
//...
}
void main()
{
AircraftCarrier c1(AircraftCarrierParameters());
AircraftCarrier c2(c1.params().setSpeed(30));
}

Virtual function issue in C++ [duplicate]

This question already has answers here:
Why is virtual function not being called?
(6 answers)
Closed 9 years ago.
AoA,
I am making a console game of chess, But I am stuck at polymorphism, below is the classes and functions definitions
/* old Part
//Base Class
class Piece /*Parent class */
{
protected:
Position* pCoord;
std::string color;
char symbol;
public:
Piece(Position* Coord,std::string Color,char symbol);
Position GetCurrentPos();
std::string GetColor();
void SetColor(std::string color);
void Draw();
virtual bool SetPos(Position* newPos){MessageBox(NULL,L"Virtual Running",L"Error",MB_OK); return true;};
virtual ~Piece();
};
/* Inherited classes */
//Child classes
class Pawn: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Pawn(Position* Coord,std::string Color,char symbol);
~Pawn();
std::vector<Position>* GetThreatendFields();
bool isValidMove(Position* newPos);
bool SetPos(Position* newPos);
};
//Child classes
class Bishops: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Bishops(Position* Coord,std::string Color,char symbol);
~Bishops();
std::vector<Position>* GetThreatendFields();
bool isValidMove(Position* newPos);
bool SetPos(Position* newPos);
};
//Here is the implementation of child class function SetPos
bool Pawn::SetPos(Position* newPos)
{
bool isSet = false;
this->pCoord = new Position();
this->pCoord = newPos;
isSet = true;
MessageBox(NULL,L"Child function running",L"Yuhuu!",MB_OK);
return isSet;
}
class ChessBoard
{
private:
Position ptr; //dummy
int SelectedPiece;
vector<Piece> pPieceSet;
bool isSelected;
public:
ChessBoard();
~ChessBoard();
void ShowPieces(Player *p1,Player *p2);
void Draw();
void MouseActivity();
void Place(Piece& p);
};
//it just shows the peices acquired from player objects..dummy vector pointer
void ChessBoard::ShowPieces(Player* p1,Player* p2)
{
std::vector<Piece>* vPiece = p1->GetPieces();
for( int i=0;i<vPiece->size();i++ )
{
Piece& piece = vPiece->at(i);
Place(piece);
piece.Draw();
}
vPiece = p2->GetPieces();
for( int i=0;i<vPiece->size();i++ )
{
Piece& piece = vPiece->at(i);
Place(piece);
piece.Draw();
}
}
*/
/*new part
I did what you say
Player::std::vector<Piece*> *vPieceSet;
Player::Player(int turn)
{
this->turn = turn%2;
this->vPieceSet = new std::vector<Piece*>;
}
void Player::Initialize() //Initial and final ranges for position
{
//Initialization of pieces to their respective position
Position pos;
Piece *pPiece;
if( this->turn == 0 )
{
this->SetName("Player 1");
for( int i=8;i<16;i++ )
{
pos.SetPosition(i);
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
this->vPieceSet->push_back(pPiece);
}
//other classes same as above
}
It runs fine at initialzation function(stores all classes fine) but when use function to get the vector object
std::vector<Piece*>* Player::GetPieces()
{
std::vector<Piece*>* tPieces = this->vPieceSet;
return tPieces;
}
//In main.cpp
it doesnot return the vector object
Player p1(0),p2(1);
p1.Initialize();
p2.Initialize(); //initialization done perfectly while debugging
vector<Piece*> *obj = p1.GetPieces(); //returns garbage
Piece* pObj = obj->at(0); //garbage
cout<<pObj->GetColor(); // garbage
*/new part
Sounds like I have another problem!
When you use polymorphism, what you are really trying to do is instantiate an object of derived type and call the methods on that object through a pointer or reference to the base object.
class Foo
{
public:
virtual void DoIt () { cout << "Foo"; }
};
class Bar
:
public Foo
{
public:
void DoIt () { cout << "Bar"; }
};
int main()
{
Foo* foo = new Bar;
foo->DoIt(); // OUTPUT = "Bar"
Foo& fooRef = *foo;
fooRef.DoIt(); // OUTPUT = "Bar"
}
In order for this to work, you need to use either a pointer or a reference to the object. You can't make a copy of the object using a the base class. If you make a copy, you will slice the object.
int main()
{
Foo* foo = new Bar;
foo->DoIt(); // OK, output = "Bar"
Foo fooCopy = *foo; // OOPS! sliced Bar
fooCopy.DoIt(); // WRONG -- output = "Foo"
}
In your code, the Piece class is intended to be polymorphic, and in your ChessBoard class you have a vector of this class:
class ChessBoard
{
private:
vector<Piece> pPieceSet;
};
Since this is a vector of the Piece object itself, and not a pointer-to-Piece, anything you put in here will be sliced. You need to change pPieceSet to be a vector of pointers-to-Piece:
vector <Piece*> pPieceSet;
You have further problems in Initialize, which need to be refactored anyway. For one thing, you have another vector of Piece objects, and there are two problems here. First, it needs to be a vector of pointers, and second, why do you need another vector at all when there is already one associated with the ChessBoard? I didn't thouroughly examine your code so maybe you do need it, but this seems like an error. There should probably just be one collection of pieces, in the ChessBoard.
In your Initialize method:
Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(*pPiece);
There are a couple of problems. One, you are pushing back a sliced copy of the Piece, which will be fixed when you change your vector to store pointers. Second, if you just change this like so:
Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(pPiece); // <-- not dereferencing
You will have a new problem because you'll be storing the pointer to a local (automatic) variable. Best is to do this:
Piece* pPiece = new Pawn (...);
// ...
vPieceSet.push_back (pPiece);
Please don't forget to delete everything you new. This is best handled by using smart pointers rather than raw pointers. In C++03 we have auto_ptr, but those can't go in a vector. Instead you'll need to use Boost or something else, or just store raw pointers. In C++11, we now have unique_ptr (preferred) and shared_ptr, which can go in to a vector.
In C++11, the best solution here is to have a vector declared as:
vector <unique_ptr <Piece> > pPieceSet;
...unless you have some compelling need to use shared_ptr instead.
As others have mentioned, it is a slicing issue, and the issue is created here:
class Player
{
private:
std::string pName;
std::vector<Piece> vPieceSet; // <-- This is your problem
int turn;
public:
Player(int turn);
~Player();
void Initialize();
std::string GetName();
void SetName(std::string Name);
int GetTurn();
std::vector<Piece>* GetPieces();
};
You are storing them in the vector as instances of Piece, which is slicing off the details of the piece (e.g. the Bishop implementation). You should modify it to something like:
class Player
{
private:
std::string pName;
std::vector<Piece*> vPieceSet; // or better, use a smart pointer wrapper
int turn;
public:
Player(int turn);
~Player();
void Initialize();
std::string GetName();
void SetName(std::string Name);
int GetTurn();
std::vector<Piece*> GetPieces(); // note this change as well
};
With your additional question/edit, you are getting another unrelated problem:
void Player::Initialize() //Initial and final ranges for position
{
Position pos; // position is declared inside the scope of Initialize
Piece *pPiece;
if( this->turn == 0 )
{
this->SetName("Player 1");
for( int i=8;i<16;i++ )
{
pos.SetPosition(i);
Pawn pPawn(&pos,"blue",'P'); // you are passing the address of position to the Pawn, and Pawn is within the scope of this loop
pPiece = &pPawn; // you are storing the address of the Pawn
this->vPieceSet->push_back(pPiece);
}
// Pawn is now out of scope and pPiece points to the memory location Pawn *used* to be at (but will likely be overwritten soon).
// As soon as this function returns, you have the same problem with pos
}
You need to allocate those variables on the heap (hence the reason we suggested smart pointer wrappers).

a function instead of copy-and-paste programming

I have an object, every member variable in this object has a name which I can acquire it by calling get_name() ,what I want to do is concatenate all the names of the member variables in alphabetical order, then do something. for example:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
}
//skip the get_name(), set_name() and others
private:
string m_local_name;
T m_type_var;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
...
}
I have to hard-code like this:
object o;
string sign = o.m_base.get_name();
sign += o.m_team.get_name();
I need a function to do this instead of copying and pasting when the object varies. Anyone has an idea?
One way to do this in normal C++, provided all of the members belong to the same class or are derived from some base class will be to use variable number of arguments to a function. An example follows.
#include <stdarg.h>
string concatenateNames(int numMembers, ...)
{
string output;
va_list args;
va_start(args, numMembers);
for(int i = 0; i < numMembers; i++)
{
MemberClass *pMember = va_arg(args, MemberClass*);
output += pMember->get_name();
}
va_end(args);
return output;
}
class Object
{
public:
MemberClass x;
MemberClass y;
MemberClass z;
};
int main()
{
Object o;
string sign = concatenateNames(3, &o.x, &o.y, &o.z);
}
If the types of all the members are different, you can look into variadic templates of C++11x: http://en.wikipedia.org/wiki/Variadic_Templates, but I can't seem to find a way to do otherwise.
If variables which have name have a same type (or these types belongs one hierarchy) you can use map of these vars. Is not good way, but maybe it helps you
Example
class object
{
public:
object() //: m_team("team"), m_base("base")
{
this->vars["m_team"] = CXMLWrapper<string>("team");
//.....
}
public:
map<string, CXMLWrapper<string> > vars;
/*CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;*/
...
}
object o;
string sign;
for(auto& x : o.vars)//i cannot remember syntax of for of map
sign += x.get_name;
PS Sorry for my writing mistakes. English in not my native language.
One method is to have an external library of member names which the CXMLWrapper class updates:-
class BaseXMLWrapper
{
public:
void ListMembers (const char *parent)
{
// find "parent" in m_types
// if found, output members of vector
// else output "type not found"
}
protected:
void RegisterInstance (const char *parent, const char *member)
{
// find 'parent' in m_types
// if not found, create a new vector and add it to m_types
// find 'member' in parent vector
// if not found, add it
}
private:
static std::map <const std::string, std::vector <const std::string> >
m_types;
};
class CXMLWrapper <class T, const char *parent> : BaseXMLWrapper
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
RegisterInstance (parent, p_name);
}
// you could override assignments, copy and move constructors to not call RegisterInstance
//skip the get_name() set_name()
private:
m_local_name;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string, "object"> m_team;
CXMLWrapper<string, "object"> m_base;
...
};
This does add overhead to the construction of objects, but as it's only a constructor overhead it might not affect overall system performance much.
This looks like a "observe pattern", you just need to keep a single copy in object as a member variable "string name_;", and pass the name_s's reference into CXMLWrapper like this:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const string &name)
: local_name_(name)
{
}
//skip the get_name() set_name()
private:
const string &local_name_;
}
class object
{
public:
object()
: team_("team"),
base_("base"),
m_team(team_)
, m_base(base_)
{
}
public:
string team_;
string base_;
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
}

C++ Static Class Member and Non-default Constructor

I have this class:
class Object
{
public:
private:
float _positionX, _positionY, _positionZ;
}
I need to do check and do some math every time a new value is assigned to them, and I also use these values in various places.
I'm looking for an easier way to assign and check values than having these methods:
class Object
{
public:
float GetPositionX();
void SetPositionX(float value);
//etc
private:
float _positionX, _positionY, _positionZ;
}
So I'm trying to do something like this:
static class Vector3
{
public:
Vector3(float *valueX, float *valueY, float *valueZ)
{
_valueX = valueX;
_valueY = valueY;
_valueZ = valueZ;
}
private:
float *_valueX, *_valueY, *_valueZ;
}
class Object
{
public:
Vector3 Position;
//Position = Vector3(&_positionX, &_positionY, &_positionZ);
private:
float _positionX, _positionY, _positionZ;
}
Just so I can call it like this anywhere else in the code:
Object *myObj = new Object();
myObj->Position.x = 1; //assign, checks are done here
float myValue = myObj->Position.x; //receive, no checks needed
But the compiler complains that Vector3 doesn't have a default constructor.
I also have a bunch of Object, and I'm not sure if I'm using the static Vector3 the right way (if it won't conflict with other object's values).
How can I get this working?
Add a default constructor to Vector:
Vector3()
{
_valueX = NULL;
_valueY = NULL;
_valueZ = NULL;
}