Friend Function accessing private variables - c++

I wrote a small piece of code to test friend functions. It worked fine for methods that didn't belong to a specific class but when I tried to put it into a class all it can access is the public variables (just as any object would).
#include <iostream>
#include <conio.h>
using namespace std;
class something{
int ip = 100;
public:
int x = 100;
void getIP();
friend void cIP::changeIP(something);
};
void something::getIP(){
cout << ip << endl;
}
class cIP{
public:
int i;
cIP();
cIP(int nIP);
something some;
void changeIP(something s);
};
cIP::cIP(){
i = 100;
}
cIP::cIP(int nIP){
i = nIP;
}
void cIP::changeIP(something s){
s.ip = i;
}
s.ip brings up the error member is inaccessible.

Related

How do I access a static member of class inside an inner class?

#include <iostream>
using namespace std;
class outer {
public :
int a=10; //non-static
static int peek; //static
int fun()
{
i.show();
cout<<i.x;
}
class inner {
public :
int x=25;
int show()
{
cout<<peek;
}
};
inner i;
int outer::inner::peek=10; //here is the problem
};
int main()
{
outer r;
r.fun();
}
So this is the code. I need to give a value to the static integer.
As I compile, it gives me an error. I am currently a beginner and still learning.
Can someone explain this?
You can define the static variable outside the class definition:
#include <iostream>
class outer {
public:
int a = 10; //non-static
static int peek; //static
void fun() {
i.show();
std::cout << i.x << '\n';
}
class inner {
public:
int x = 25;
void show() {
std::cout << peek << '\n';
}
};
inner i;
};
int outer::peek = 10; // <----------- here
int main() {
outer r;
r.fun();
}
Or define it inline:
class outer {
public:
int a = 10; //non-static
static inline int peek = 10; //static inline
// ...
Note: I changed your member functions to void since they don't return anything.
Output:
10
25

Basic Class Inheritance in C++

I am typing the following code and I am getting the following error at line-1
[Error] no matching function for call to 'int_adder::add()
#include <iostream>
using namespace std;
class adder{
public:
void add(){ cout <<"adder::add() "; }
};
class int_adder : public adder{
public:
int add(int a, int b){
return (a + b);
}
};
int main(){
int_adder ia;
ia.add(); //LINE-1
cout << ia.add(10, 20); //LINE-2
return 0;
}
As pointed by others in the comment, I have corrected it:-
#include <iostream>
using namespace std;
class adder{
public:
void add(){ cout <<"adder::add() "; }
};
class int_adder : public adder{
public:
int add(int a, int b){
return (a + b);
}
};
int main(){
int_adder ia;
ia.adder::add(); //LINE-1
cout << ia.add(10, 20); //LINE-2
return 0;
}
The statement adder::add() will overide the function add() present in int_adder.
Can't fing exact dupe, but you can make overloads from base class visible by using using directive, example:
#include <iostream>
using namespace std;
class adder{
public:
void add(){ cout <<"adder::add() "; }
};
class int_adder : public adder{
public:
using adder::add; // expose base class overload as our own
int add(int a, int b){
return (a + b);
}
};
int main(){
int_adder ia;
ia.add(); //LINE-1
ia.adder::add(); // explicit name also works
cout << ia.add(10, 20); //LINE-2
return 0;
}
As the other answer mentions using base class name scope also works. It all depends on your needs and class design.
Basically defining an overload in a derived class prevents implicit method look up from matching base class overloads, so you have to be explicit about it in one way or another.
You have totally two different versions of add in the first place. You are not overriding, you are overloading. You are just providing a new add function that has nothing to do with the other add function of the parent.
So first of all, do you want to override or overload?
Overriding the parent add would like the following:
#include <iostream>
using namespace std;
class adder{
public:
void add(){ cout <<"adder::add() "; }
};
class int_adder : public adder{
public:
int add() override {cout <<"int_adder ::add() ";};
int add(int a, int b){
return (a + b);
}
};
int main(){
int_adder ia;
ia.adder::add(); //LINE-1 <- would work displays adder::add()'s message
cout << ia.add(10, 20); //LINE-2
adder ia = int_adder{}; // now this is interesting
ia.add(); // would work displays adder::add()'s message - cause you did not ask for virtuality
return 0;
}

C++: Passing a pointer of master to the worker

I am very new to pointers, so I have no idea what is going on with them.
I am trying to get a master class pass a pointer of itself to its worker/s, and I have no idea why it doesn't work.
#include <iostream>
#include <Windows.h>
using namespace std;
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
class LittleOne {
BigOne* master;
public:
LittleOne(BigOne*);
void Increment();
};
LittleOne::LittleOne(BigOne* upOne) {
master = upOne;
}
void LittleOne::Increment() {
master->increase++;
}
BigOne Outer;
int main() {
cout << Outer.increase << endl;
Outer.worker.Increment();
cout << Outer.increase << endl;
system("PAUSE");
}
This is my problem boiled down to its core components.
The problem isn't with pointers. It's mostly here:
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
When you define workers, what is LittleOne? How is it laid out in memory? How is it initialized? The compiler can't know, it hasn't seen the class definition yet. So you must flip the definitions around:
class BigOne;
class LittleOne {
BigOne* master;
public:
LittleOne(BigOne*);
void Increment();
};
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
The forward declaration allows us to define members that accept and return pointers. So the class LittleOne can have its definition written before BigOne. And now BigOne can define members of type LittleOne by value.
The issue is with forward declaration.
You can refer the following link for more details and explanation.
What are forward declarations in C++?

How to pass a private member variable to another class?

Based on my Snack.cpp, Snack header file, MiniVend header file & miniVend.cpp file, I am trying to move my Snack private member - price into my MiniVend.cpp file to generate the amount * price to return a total value of items in my machine. How do I access the price from another class?
Portion of my miniVend.cpp file
double miniVend::valueOfSnacks()
{
return //// I don't know how to get snacks price in here? I need to access snacks & getSnackPrice.
}
miniVend header
#ifndef MINIVEND
#define MINIVEND
#include <string>
#include "VendSlot.h"
#include "Snack.h"
using std::string;
class miniVend
{
public:
miniVend(VendSlot, VendSlot, VendSlot, VendSlot, double); //constructor
int numEmptySlots();
double valueOfSnacks();
//void buySnack(int);
double getMoney();
~miniVend(); //desructor
private:
VendSlot vendslot1; //declare all the vending slots.
VendSlot vendslot2; //declare all the vending slots.
VendSlot vendslot3; //declare all the vending slots.
VendSlot vendslot4; //declare all the vending slots.
double moneyInMachine; //money in the machine
};
#endif // !MINIVEND
Snack.cpp
#include "Snack.h"
#include <iostream>
#include <string>
using std::endl;
using std::string;
using std::cout;
using std::cin;
Snack::Snack() //default constructor
{
nameOfSnack = "bottled water";
snackPrice = 1.75;
numOfCalories = 0;
}
Snack::Snack(string name, double price, int cals)
{
nameOfSnack = name;
snackPrice = price;
numOfCalories = cals;
}
Snack::~Snack()
{
}
string Snack::getNameOfSnack()
{
return nameOfSnack;
}
double Snack::getSnackPrice()
{
return snackPrice;
}
int Snack::getNumOfCalories()
{
return numOfCalories;
}
Snack.h file
#ifndef SNACK_CPP
#define SNACK_CPP
#include <string>
using std::string;
class Snack
{
private:
string nameOfSnack;
double snackPrice;
int numOfCalories;
public:
Snack(); //default constructor
Snack(string name, double price, int cals); //overload constructor
~Snack(); //destructor
//Accessor functions
string getNameOfSnack(); //returns name of snack
double getSnackPrice(); //returns the price of the snack
int getNumOfCalories(); //returns number of calories of snack
};
#endif // !SNACK_CPP
Assuming getSnackPrice() is public, and Snack.h does exist, you should just be able to call
snackObject.getSnackPrice() * ammount
what you need is friend keyword. Define the
friend class className;
I don't really understand why you don't just implement get()? Accessing private data is really bad. You are breaking the encapsulation. But if you really want to know (i.e. you should NOT do it, it is really BAD), then you just return a reference to a private data as shown below
#include <iostream>
class A
{
public:
A(int a) : x(a) {}
int &getPrivateDataBAD() { return x; }
void print() { std::cout << x << std::endl; }
private:
int x;
};
class B
{
public:
void print(int &s) { std::cout << s << std::endl; }
};
int main()
{
A obj(2);
B bObj;
bObj.print( obj.getPrivateDataBAD() );
return 0;
}

Multilevel inheritance/polymorphism and virtual function

I have a multilevel inheritance (from Ship class -> MedicShip class -> Medic class) with virtual function code as below. I suppose the result should be :
Medic 10
Medic 10
But it generated strange result. On the other hand, if I only use one level inheritance (from Ship class -> Medic class without MedicShip class in between) the result will be OK. Could you find my mistake please? Many thank....
#ifndef FLEET_H
#define FLEET_H
#include <string>
#include <vector>
using namespace std;
class Ship
{
public:
Ship(){};
~Ship(){};
int weight;
string typeName;
int getWeight() const;
virtual string getTypeName() const = 0;
};
class MedicShip: public Ship
{
public:
MedicShip(){};
~MedicShip(){};
string getTypeName() const;
};
class Medic: public MedicShip
{
public:
Medic();
};
class Fleet
{
public:
Fleet(){};
vector<Ship*> ships;
vector<Ship*> shipList() const;
};
#endif // FLEET_H
#include "Fleet.h"
#include <iostream>
using namespace std;
vector<Ship*> Fleet::shipList() const
{
return ships;
}
int Ship::getWeight() const
{
return weight;
}
string Ship::getTypeName() const
{
return typeName;
}
string MedicShip::getTypeName() const
{
return typeName;
}
Medic::Medic()
{
weight = 10;
typeName = "Medic";
}
int main()
{
Fleet fleet;
MedicShip newMedic;
fleet.ships.push_back(&newMedic);
fleet.ships.push_back(&newMedic);
for (int j=0; j< fleet.shipList().size(); ++j)
{
Ship* s = fleet.shipList().at(j);
cout << s->getTypeName() << "\t" << s->getWeight() << endl;
}
cin.get();
return 0;
}
You haven't created any instances of class Medic. Did you mean to say
Medic newMedic;
instead of
MedicShip newMedic;
perhaps? So, the Medic constructor isn't being called and weight and typeName aren't being initialized.
~Ship(){};
The first mistake is right here. This destructor should be virtual if you want to delete derived class objects through base class pointer.