Sign in to follow this  

alternative to friend class?

This topic is 2387 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[code]
#include <iostream>
using namespace std;

class CWeapon
{
protected:
std::string m_strName;
float m_fReloadRatio;
int m_iAmmo;
int m_iDamage;
public:
CWeapon::CWeapon( std::string Name, float fReloadRatio, int iAmmo, int iDamage) : m_strName(Name), m_fReloadRatio(fReloadRatio), m_iAmmo(iAmmo), m_iDamage(iDamage) { }
std::string GetWeaponName() { return m_strName; }
float GetReloadRatio() { return m_fReloadRatio; }
int GetAmmo() { return m_iAmmo; }
int GetDamage() { return m_iDamage; }
virtual void DisplayWeaponInfo();
void Shoot( int iNumTimeToShoot ) { --m_iAmmo; }
};

void CWeapon::DisplayWeaponInfo()
{
std::cout << m_strName.c_str() << std::endl;
std::cout << m_fReloadRatio << std::endl;
std::cout << m_iAmmo << std::endl;
std::cout << m_iDamage << std::endl;
}

class CShotgun : public CWeapon
{
protected:
int m_iGrenadeAmmo;
public:
// shotguns shoot 2 bullets at once
virtual void Shoot( int iNumTimeToShoot )
{
m_iAmmo -= 2;
}
void ShootGrenade( int iNumTimeToShoot )
{
--m_iGrenadeAmmo;
}
virtual void DisplayWeaponInfo();

};

void CShotgun::DisplayWeaponInfo()
{
std::cout << m_strName.c_str() << std::endl;
std::cout << m_fReloadRatio << std::endl;
std::cout << m_iAmmo << std::endl;
std::cout << m_iDamage << std::endl;
std::cout << m_iGrenadeAmmo << std::endl;
}

class CMonster
{
private:
std::string m_strName;
int m_iHealth;
int m_iLives;
float m_fHpRegenRatio;
CShotgun m_SShotgun;
public:
CMonster::CMonster()
{
m_strName = "Michael";
m_iHealth = 100;
m_iLives = 5;
m_fHpRegenRatio = .25;
}
std::string GetMonsterName() { return m_strName; }
int GetMonsterHealth() { return m_iHealth; }
int GetMonsterLives() { return m_iLives; }
float GetMonsterHpRegenRatio() { return m_fHpRegenRatio; }
CWeapon GetMonsterWeapon() { return m_SShotgun; }
void DisplayMonsterInfo();
void ShootSelf( int inumTimes );
};

void CMonster::DisplayMonsterInfo()
{
std::cout << m_strName.c_str() << std::endl;
std::cout << m_iHealth << std::endl;
std::cout << m_iLives << std::endl;
std::cout << m_fHpRegenRatio << std::endl;
m_SShotgun.DisplayWeaponInfo();
}

void CMonster::ShootSelf( int iNumTimes )
{
for(int i = 0; i < iNumTimes; i++ ) {
m_SShotgun.Shoot( iNumTimes );
m_iHealth -= m_SShotgun.GetDamage();
}
}


int main()
{
std::cout << "Just now entering inside of main" << std::endl << std::endl;

std::cout << "Initializing local struct without blocks" << std::endl;
CMonster firstMonster;
std::cout << "//////////////////////////////////////" << std::endl;
std::cout << "Call void void CMonster::DisplayerMonsterInfo()" << std::endl;
firstMonster.DisplayMonsterInfo();
std::cout << "//////////////////////////////////////" << std::endl;

std::cout << "//////////////////////////////////////" << std::endl;
std::cout << "Call void void CMonster::ShootSelf( int iNumTimes )" << std::endl;
firstMonster.ShootSelf( 2 );
std::cout << "//////////////////////////////////////" << std::endl;

std::cout << "//////////////////////////////////////" << std::endl;
std::cout << "Call void void CMonster::ShootGrenade( int iNumTimes )" << std::endl;
[b][u]firstMonster.m_SShotgun.ShootGrenade( 1 );[/u][/b]
std::cout << "//////////////////////////////////////" << std::endl;

std::cout << "//////////////////////////////////////" << std::endl;
std::cout << "Call void void CMonster::DisplayerMonsterInfo()" << std::endl;
firstMonster.DisplayMonsterInfo();
std::cout << "//////////////////////////////////////" << std::endl;

getchar();
getchar();
std::cout << "Now exiting main" << std::endl;
return 0;
}
[/code]


[b][u]firstMonster.m_SShotgun.ShootGrenade( 1 ); cannot access private member declared in CMonster
[/u][/b]i know i can easily get past the error by creating a friend class but i don't want to do this! does anyone have any suggestions i can use in order to allow this line of code to have permission to execute?


Share this post


Link to post
Share on other sites
[quote name='Texus' timestamp='1306863307' post='4817948']
Why don't you use protected instead of private?
[/quote]

it is because he is trying to access the shotgun from main, not because he is trying to access shotgun.someMethod() from monster. edit: if you did mean the shotgun, making it protected will have the same problem because main isn't part of a subclass of monster.

What you want to do is create a method in monster ShootGrenade() that calls [b]m_SShotgun.ShootGrenade( 1 ).

[/b]Make that method public, then you should be able to call that in main. Either that or make m_SShotgun public or make a public accessor for it. Though I recommend the first way.

Share this post


Link to post
Share on other sites
Looks like some of your code is too familiar with certain objects.

Consider this line: [color="#1C2837"][size="2"][color="#000000"]firstMonster[/color][color="#666600"].[/color][color="#000000"]m_SShotgun[/color][color="#666600"].[/color][color="#660066"]ShootGrenade[/color][color="#666600"]([/color] [color="#006666"]1[/color] [color="#666600"]);[/color][/size][/color]

It assumes you know that monsters have shotguns, and also it assumes that the shotgun will also shoot grenades.



Is it possible that they have a different weapon? Is it possible that they don't have a shotgun at all? Do all shotguns fire grenades? (Seems like a grenade launcher is a different weapon than a shotgun...)


Instead of having such tight coupling, you might try a more general public interface at the base class:

[source lang='c++']
// Get the shotgun
Weapon* weapon = firstMonster.GetPrimaryWeapon();
if(weapon && weapon->CanAttack() )
{
weapon->Attack(1);
}

// This shotgun also has grenades in its secondary attack
if(weapon && weapon->CanAttackSecondary() )
{
weapon->AttackSecondary(1);
}
[/source]

If the grenades have nothing to do with the shotgun, then they need to be something else.

Perhaps if grenades are weapons, you can treat them as such. They are a weapon with various weapon properties, so perhaps an accessor to get the grenade weapon pointer. If they aren't weapons but are instead some sort of inventory item, you'd want to have a ThrowGrenade function on that class instead.

Share this post


Link to post
Share on other sites
[quote name='shoez' timestamp='1306863086' post='4817946']
does anyone have any suggestions i can use in order to allow this line of code to have permission to execute?[/quote]

First, why do you think it should be able to execute? What does it mean? Why do you know the monster has a shotgun that can fire grenades? Why are you reaching over the monster's shoulder and pulling the trigger on its weapon instead of letting it do the work?

Share this post


Link to post
Share on other sites

This topic is 2387 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this