LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-19-2015, 10:47 PM   #1
retroCheck
Member
 
Registered: Jan 2015
Posts: 34

Rep: Reputation: Disabled
Creating a class object inside another class's constuctor


I have a Hand class and a Player class. I want the player to own the hand so I am thinking I need a prototype in the Player.h and then in my Player.ccp constructor create it. This is not working. I keep getting an "incomplete type" error. Not sure how I should approach this issue. Am I defeating the purpose of OO by trying to do this way? Any help would be great, thanks.

My player class -
Code:
myHand("deck");
My Player header -
Code:
Hand myHand;
 
Old 02-20-2015, 12:29 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,609

Rep: Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105
I couldn't compile your example program, maybe you left out important parts.
 
Old 02-20-2015, 02:52 AM   #3
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 11,507

Rep: Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456Reputation: 3456
(so would be nice to give more details, probably some sources) Otherwise the problem is in line 34.
 
Old 02-20-2015, 04:27 AM   #4
a4z
Senior Member
 
Registered: Feb 2009
Posts: 1,727

Rep: Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739
the compiler needs to see the whole Hand class where it needs to see it, this is where it needs to know the size,

if your Player.h declares a value object of type Hand, this is the point where the compiler need to know everything about Hand.
so you it seems you need to include Hand.h in Player.h

please have a look at
http://www.linuxquestions.org/questi...gs-4175464257/
 
1 members found this post helpful.
Old 02-20-2015, 04:39 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,609

Rep: Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105
Or use pointers:
Code:
/* player.h */

class Hand;

class Player {
    Hand *hand;
}
 
1 members found this post helpful.
Old 02-20-2015, 07:10 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191Reputation: 1191
The two choices for dealing with the incomplete type were given by az4 and NevemTeve.

But, seperate from those details, I can't see how your line of code could be correct:
Code:
myHand("deck");
Where is that line of code and does it really end with a ; and if so, how could it be correct?

I would have expected something like:
Code:
Player::Player( ... ) :
   ...
   myHand("deck"),
   ...
{
   ...
}
or (if you take NevemTeve's suggestion):
Code:
Player::Player( ... ) :
   ...
   myHand( new Hand("deck") ),
   ...
{
   ...
}
Most unskilled C++ coders would write something like:

Code:
Player::Player( ... )
{
   ...
   myHand = Hand("deck");
   ...
}
That ends in ; but is not the line you wrote. It is also an inferior constructor style for several reasons.

Last edited by johnsfine; 02-20-2015 at 07:13 AM.
 
Old 02-20-2015, 07:18 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,609

Rep: Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105
Off: the last point could be argued http://yosefk.com/c++fqa/ctors.html#fqa-10.6
 
Old 02-20-2015, 07:36 AM   #8
retroCheck
Member
 
Registered: Jan 2015
Posts: 34

Original Poster
Rep: Reputation: Disabled
I usually do post code but I was thinking my whole approach was wrong, not the code.

I tried something different this time. Like what a4z mentioned, I tried creating the Hand object within the Player class but now I am getting errors everywhere I use a method from the Hand class. Example - myHand.addCard(myDeck->dealOne());

Nevemteve, to use a pointer as you mentioned wouldn't I need to pass that in through the constructor?

Code:
//Player.cpp

#include <iostream>
#include "Player.h"
#include "Card.h"
#include "Hand.h"
#include "Deck.h"


using namespace std;

Hand myHand(string assocDeck);

Player::Player(Deck *deck){
	//Name will be set after game determine num of players
	_name = "";
	myHand(deck->getName());
	myDeck = deck;
	//No way to bust on first two cards so bust = 0.
	bust = 0;
	//Player will choose to stay
	stay = 0;
}

Player::~Player(){}
	


int Player::hits(){
	//add card and then determine if busted.
	myHand.addCard(myDeck->dealOne());
	if(getHandValue()  > 21){
		bust = 1;
	}	
}

void Player::stays(){
	stay = 1;
}

int Player::getBust(){
	return bust;
}

void Player::resetBust(){
	bust = 0;
}


void Player::printHand(){
	myHand.printHand();
}

void Player::setName(string name){
	//Not allowing more then ten chars for a name
	//Need output to be readable.
	if(name.length() < 11 && name.length() > 0){
		_name = name;
	}else{
		cout << endl << "Name is too long, ten characters is the limit." << endl;
	}

	
}

void Player::clearHand(){
	myHand.clearHand();
}

int Player::getHandValue(){
	myHand.getHandTotal();
	//return  myHand->getHandTotal();
}

string Player::getName(){
	return _name;
}	

int Player::getStays(){
	return stay;
}
Code:
#include <string>
class Deck;
class Hand;

class Player{
	public:
		//Constructor
		Player(Deck *deck);
		//Destructor
		~Player();
		//Set name of player
		void setName(std::string name);
		//Get name of player
		std::string getName();
		//hit, add one card to hand
		int hits();
		//Decline to add cards
		void stays();
		//Print hand
		void printHand();
		//Get total of card in hand
		int getHandValue();
		//clear hand which free up memory
		void clearHand();
		//Determine if player has busted.
		int getBust();
		//get stay value
		int getStays();
		//Reset bust
		void resetBust();

	private: 
		
		std::string _name;//Name
		//Ptr for player's hand

		//Ptr for player's deck
		Deck *myDeck;
		
		int stay;
		int bust;
};
 
Old 02-20-2015, 08:10 AM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,609

Rep: Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105
Be a good boy and create a small, complete, minimal example...
 
Old 02-20-2015, 08:24 AM   #10
retroCheck
Member
 
Registered: Jan 2015
Posts: 34

Original Poster
Rep: Reputation: Disabled
Be a good boy???

It comes down to just the first 13 lines of code in the player class. I posted all the other code because of recent comments.
 
Old 02-20-2015, 08:38 AM   #11
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,609

Rep: Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105Reputation: 1105
All I ask is a complete, minimal example that compiles in itself (or shows the compilation error you want to demonstrate).
 
Old 02-20-2015, 12:14 PM   #12
a4z
Senior Member
 
Registered: Feb 2009
Posts: 1,727

Rep: Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739
Hand myHand is not in the player hpp

#include "Hand.h" needs to go into hpp

you can not call a constructor on myHand when myHand is already initialized

you need to make this in the construction itself
search for class member initialization
it looks like this
Code:
Player::Player(Deck *deck)
:  _name ( "")
, myDeck(deck)
, myHand(deck->getName())
, bust (0)
{

}
 
Old 02-20-2015, 12:33 PM   #13
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 167

Rep: Reputation: Disabled
Quote:
Originally Posted by retroCheck View Post
I usually do post code but I was thinking my whole approach was wrong, not the code.

I tried something different this time. Like what a4z mentioned, I tried creating the Hand object within the Player class but now I am getting errors everywhere I use a method from the Hand class. Example - myHand.addCard(myDeck->dealOne());

Nevemteve, to use a pointer as you mentioned wouldn't I need to pass that in through the constructor?

Code:
//Player.cpp

#include <iostream>
#include "Player.h"
#include "Card.h"
#include "Hand.h"
#include "Deck.h"


using namespace std;

Hand myHand(string assocDeck);

Player::Player(Deck *deck){
	//Name will be set after game determine num of players
	_name = "";
	myHand(deck->getName());
	myDeck = deck;
	//No way to bust on first two cards so bust = 0.
	bust = 0;
	//Player will choose to stay
	stay = 0;
}

Player::~Player(){}
	


int Player::hits(){
	//add card and then determine if busted.
	myHand.addCard(myDeck->dealOne());
	if(getHandValue()  > 21){
		bust = 1;
	}	
}

void Player::stays(){
	stay = 1;
}

int Player::getBust(){
	return bust;
}

void Player::resetBust(){
	bust = 0;
}


void Player::printHand(){
	myHand.printHand();
}

void Player::setName(string name){
	//Not allowing more then ten chars for a name
	//Need output to be readable.
	if(name.length() < 11 && name.length() > 0){
		_name = name;
	}else{
		cout << endl << "Name is too long, ten characters is the limit." << endl;
	}

	
}

void Player::clearHand(){
	myHand.clearHand();
}

int Player::getHandValue(){
	myHand.getHandTotal();
	//return  myHand->getHandTotal();
}

string Player::getName(){
	return _name;
}	

int Player::getStays(){
	return stay;
}
Code:
#include <string>
class Deck;
class Hand;

class Player{
	public:
		//Constructor
		Player(Deck *deck);
		//Destructor
		~Player();
		//Set name of player
		void setName(std::string name);
		//Get name of player
		std::string getName();
		//hit, add one card to hand
		int hits();
		//Decline to add cards
		void stays();
		//Print hand
		void printHand();
		//Get total of card in hand
		int getHandValue();
		//clear hand which free up memory
		void clearHand();
		//Determine if player has busted.
		int getBust();
		//get stay value
		int getStays();
		//Reset bust
		void resetBust();

	private: 
		
		std::string _name;//Name
		//Ptr for player's hand

		//Ptr for player's deck
		Deck *myDeck;
		
		int stay;
		int bust;
};
You have several illegal constructs.

Here:
Code:
Hand myHand(string assocDeck);
You are constructing an object using a Hand constructor (presumably it exists?) and then, where a parameter list should be, you are trying to declare a string called assocDeck - which won't pass the compiler.

Here:
Code:
Player::Player(Deck *deck){
	//Name will be set after game determine num of players
	_name = "";
	myHand(deck->getName());
	myDeck = deck;
you take an object that you tried to construct, myHand, and calling it like it is a function. The compiler won't like that.

You should be include <string> in your implementation file and you could read up on header guards.

Last edited by SoftSprocket; 02-20-2015 at 12:34 PM.
 
Old 02-21-2015, 09:33 AM   #14
retroCheck
Member
 
Registered: Jan 2015
Posts: 34

Original Poster
Rep: Reputation: Disabled
a4z - I tried what you suggested but the compiler kept squawking at me for adding Hand header to Player header. I received a error in Class.cpp. I did get it work and while I do no think it is a bad way of doing it I know I easily could be wrong in assuming that. Here is what I did. I added Hand *myHand to top of Player.cpp and in the constructor {...myHand = new Hand(deck->getName());...}

SoftSprocket - those illegal constructs were me frustrated and throwing stuff out there to see if it would stick. I know I know, not the way to go about it.
 
Old 02-21-2015, 11:09 AM   #15
a4z
Senior Member
 
Registered: Feb 2009
Posts: 1,727

Rep: Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739Reputation: 739
Quote:
Originally Posted by retroCheck View Post
a4z - I tried what you suggested but the compiler kept squawking at me for adding Hand header to Player header.
this makes no sense, there is a problem but very possible not on the location you expect.
what you post is incomplete and not enough to fix the problem,
put the stuff on github or somewhere else if you want to make it easy to help and you are not able to reduce the problem so that what you post is reproducible.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Why can't we access a protected member in a derived class by a base class's object? TheIndependentAquarius Programming 5 02-04-2012 11:35 PM
[SOLVED] C++ Class object can't find class methods TheCrow33 Programming 4 01-29-2012 06:04 PM
Derived class inside parent class array, possible? xemous Programming 3 10-17-2006 12:35 PM
C++ class-object? shivaligupta Programming 2 01-06-2005 03:25 AM
Event driven object-to-object: C++ template class mecanism ( NOT STL or STDC++) bretzeltux Programming 2 12-23-2003 03:45 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:26 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration