Accessibility of a friend function - c++

class C2; //Forward Declaration
class C1
{
int status;
public:
void set_status(int state);
void get_status(C2 y);
};
class C2
{
int status;
public:
void set_status(int state);
friend void C1::get_status(C2 y);
};
//Function Definitions
void C1::set_status(int state)
{
status = state;
}
void C2::set_status(int state)
{
status = state;
}
void C1::get_status(C2 y) //Member function of C1
{
if (y.status | status)
cout<<" PRINT " <<endl;
}
y.status in the second last line displays an error:
C2::status is inaccessible
The code executes properly, but there is a red line (error) under y.status.
Why is this?

It sounds to me like the compiler (or part of a compiler) used by your IDE has a problem. I added enough to your code to get a complete program:
#include <iostream>
using namespace std;
class C2; //Forward Declaration
class C1
{
int status;
public:
void set_status(int state);
void get_status(C2 y);
};
class C2
{
int status;
public:
void set_status(int state);
friend void C1::get_status(C2);
};
//Function Definitions
void C1::set_status(int state) {
status = state;
}
void C2::set_status(int state) {
status = state;
}
void C1::get_status(C2 y) //Member function of C1
{
if (y.status | status)
cout << " PRINT " << endl;
}
int main() {
C1 c;
C2 d;
d.set_status(1);
c.get_status(d);
}
This compiled (without errors or warnings, at with default flags) with g++ 4.9 and VC++ 12 (aka VC++ 2013). Both produced: PRINT as output.
It's pretty common for an IDE to parse the source code separately from the actual compiler, and some of them are fairly limited compared to real compilers, so I guess it's not terribly surprising that they get confused about some things.

Related

How to pass smart pointer instead of "this" in C++ 11?

I am using c++11 compiler.
I have two classes - class Test and class TestHelper.
The class Test is a friend-to-class TestHelper.
The class Test is only which we can access from outside.
Now, we want to call Test API i.e. setVal(). This setVal() should call
Test2 API i.e. setX and is expecting this pointer. I don't want to use this pointer but want
to use a smart pointer instead. How can I do so?
The notion of this kind of desirability is because of the fact that in reality, my class Test is pretty big. So, I am trying to make a helper class for Test i.e.
class TestHelper;
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(this, 324);
}
};
class TestHelper
{
public:
void setX(Test *test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
};
int main()
{
std::cout << "Hello World!\n";
Test x;
x.setVal(130);
}
I tried changing the prototype from void setX(Test *test, int val)
to void setX(std::shared_ptr<Test> test, int val) but don't know how to pass this pointer
as std::shared_ptr<Test> test here.
So here is working solution with shared pointers. The example doesn't even compile due to missing definitions so you have to restructure your code into headers and cpp files.
Test.h:
#ifndef TEST_H
#define TEST_H
#include <memory>
#include "TestHelper.h"
class Test : public std::enable_shared_from_this<Test>
{
private:
friend class TestHelper;
int x;
public:
void display();
void setVal(int val);
};
#endif
Test.cpp:
#include <iostream>
#include "Test.h"
void Test::display() {
std::cout << x;
}
void Test::setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
TestHelper.h:
#ifndef TESTHELPER_H
#define TESTHELPER_H
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
#endif
TestHelper.cpp:
#include <memory>
#include "TestHelper.h"
#include "Test.h"
void TestHelper::setX(std::shared_ptr<Test> test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
main.cpp:
#include <iostream>
#include <memory>
#include "Test.h"
int main(void){
std::cout << "Hello World!\n";
auto x = std::make_shared<Test>();
x->setVal(130);
x->display();
}
You can run it here: https://paiza.io/projects/e/79dehCx0RRAG4so-sVZcQw
I don't understand why you want this, here's a few variants that compile
reference
// Reference variant
#include <iostream>
class Test;
class TestHelper
{
public:
void setX(Test & test, int val);
};
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(*this, 324);
}
};
void TestHelper::setX(Test &test, int val)
{
/** some algorithm here and then change val to something else */
test.x = val*100;
}
int main()
{
Test x;
x.setVal(130);
x.display();
}
http://cpp.sh/7t3ec
shared ptr
// Shared ptr variant
#include <iostream>
#include <memory> // Required for shared_ptrs
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
class Test : public std::enable_shared_from_this<Test>
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
};
void TestHelper::setX(std::shared_ptr<Test> test, int val)
{
/** some algorithm here and then change val to something else */
test->x = val*100;
}
int main()
{
auto x = std::make_shared<Test>(); // x needs to be created as shared_ptr or it won't work
x->setVal(130);
x->display();
}
http://cpp.sh/87ao2
Perhaps with these you can refine your question?

Pass a function pointer to a class object

I need to be able to specify a function for a class to be able to run (a callback function?) as part of a menu system, my knowledge of c++ is stretched here. Obviously this won't compile but hopefully it gives an idea of what I'm trying to do -
void testFunc(byte option) {
Serial.print("Hello the option is: ");
Serial.println(option);
}
typedef void (*GeneralFunction)(byte para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction *functionName;
public:
void doFunction() {
functionName;
}
};
testClass test { *p_testFunc(123) };
void setup() {
Serial.begin(9600);
test.doFunction();
}
void loop() {
}
I am aware of some std:: options but Arduino doesn't have them implemented unfortunately.
Edit: The compiler output for this code -
sketch_mar10a:17:29: error: void value not ignored as it ought to be
testClass test { *p_testFunc(123) };
^
sketch_mar10a:17:35: error: no matching function for call to 'testClass::testClass(<brace-enclosed initializer list>)'
testClass test { *p_testFunc(123) };
^
Please find the below code, see if this helps,you need a constructer to take the parameter, also you can't call the function from the parameter list while its expecting a function pointer
#include <iostream>
using namespace std;
void testFunc(int option) {
std::cout<<"in fn "<<option;
}
typedef void (*GeneralFunction)(int para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction functionName;
int param1;
public:
testClass(GeneralFunction fn,int par1):functionName(fn),param1(par1){}
void doFunction() {
functionName(param1);
}
};
testClass test (p_testFunc,123);
void setup() {
test.doFunction();
}
void loop() {
}
int main()
{
setup();
return 0;
}
Thanks to Bibin I have adapted his code to suit Arduino, separated the constructor, and initialized the class in setup().
void testFunc(byte option) {
Serial.print("Hello the option is: ");
Serial.println(option);
}
typedef void (*GeneralFunction)(byte para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction functionName;
byte param1;
public:
testClass(GeneralFunction fn, int par1);
void doFunction() {
functionName(param1);
}
};
void setup() {
Serial.begin(9600);
testClass test (p_testFunc, 123);
test.doFunction();
}
void loop() {
}
testClass::testClass(GeneralFunction fn, int par1) //constructor
: functionName(fn), param1(par1) {}
Which outputs:
Hello the option is: 123

error C2509: member function not declared in derived class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have base class State and derived class InitialState.When i build solution compiler show error C2509: 'setView': member function not declared in 'InitialState' and I don't know why...
Here is State.h :
#ifndef STATE_H
#define STATE_H
#include<iostream>
using namespace std;
class State {
public:
State() { isPrototype = true; }
virtual void execute() = 0;
virtual void setView(ostream& screen) const = 0;
virtual void onEnter() { system("CLS"); setView(cout); }
virtual void onExit() = 0;
private:
bool isPrototype;
State* nextState;
};
#endif
InitialState.h :
#ifndef INITIAL_STATE_H
#define INITIAL_STATE_H
#include"State.h"
class InitialState : public State {
public:
void execute() {}
void onExit() {}
void setView(ostream& screen) const;
};
#endif
and InitialState.cpp:
#include"InitialState.h"
void InitialState::setView(ostream& screen) const {
screen << "Welcome!" << endl;
screen << "Please select what you want to do: " << endl << "1.Load card" << endl << "0.Exit" << endl;
}
I have tried to add key word "virtual" in the front of functions in InitialState.h , but it doesn't change anything...also when I delete InitialState.cpp the code compiles normaly.
Here is the AtmTest.cpp:
#include "PaymentCard.h"
//#include "Atm.h"
int main() {
return 0;
}
but it has nothing with State...
and here are the other classes:
Atm.h:
#ifndef ATM_H
#define ATM_H
#include<iostream>
using namespace std;
class Atm {
public:
static Atm* get();
static void release() { delete instance; instance = nullptr; } //Singleton
private:
int serialNumber;
string bankName;
string location;
//Singleton:
Atm();
static Atm* instance;
Atm(const Atm& m) = delete;
Atm& operator=(const Atm& m) = delete;
Atm(Atm&&) = delete;
Atm& operator=(Atm&& m) = delete;
};
#endif
Atm.cpp:
#include"Atm.h"
//Singleton:
Atm* Atm::instance = nullptr;
Atm* Atm::get() {
if (instance == nullptr) {
instance = new Atm();
}
return instance;
}
PaymentCard.h:
#ifndef PAYMENT_CARD_H
#define PAYMENT_CARD_H
#include<iostream>
using namespace std;
class PaymentCard {
public:
PaymentCard(string clientName);
void addMoney(unsigned int amount) { currentAmount += amount; }
void withdrawMoney(int amount);
friend ostream& operator<< (ostream&, const PaymentCard&);
private:
static int NumberGenerator;
unsigned int serialNumber;
string clientName;
int currentAmount;
};
#endif
PaymentCard.cpp:
#include"PaymentCard.h"
int PaymentCard::NumberGenerator = 0;
PaymentCard::PaymentCard(string clientName) {
currentAmount = 0;
this->clientName = clientName;
serialNumber = NumberGenerator++;
}
void PaymentCard::withdrawMoney(int amount) {
if (amount > currentAmount)cout << "Ovde ide izuzetak";
else currentAmount -= amount;
}
ostream& operator<< (ostream &os, const PaymentCard& card){
os << card.serialNumber + 1 << ". Client: " << card.clientName << endl;
return os;
}
This code is not near the finish, but it worked until i have made SetView in InitialState, so idk what happened..
The problem: InitialState.h is precompiled, and you are linking to a prior version of InitialState.h. Clean, rebuild, and/or disable precompiled headers altogether.
I suspect that, because:
I can reproduce the error by commenting out the declaration of setView() in InitialState.h
The resulting error message refers to line 3 of InitialState.cpp and the error message you posted refers to line 6, which indicates that the posted source code did not produce that error message.
To reproduce the error, one has to comment out the setView() decalration from the InitialState class:
class InitialState : public State {
public:
void execute() {}
void onExit() {}
//void setView(ostream& screen) const;
};
Then one gets the following error message:
1>InitialState.cpp(3): error C2509: 'setView' : member function not declared in 'InitialState'
1> c:\users\laci\desktop\samples\stackoverflow\InitialState.h(6) : see declaration of 'InitialState'

Member functions not getting inherited in c++

The following code has three classes. account, savings(derived), current(derived). But three of the memberfunctions from the base class are not getting inherited. This is the error what I get. Is it possible doing without using virtual functions
In file included from main.cpp:1:0:
classes.hpp:96:30: error: no ‘void savingsAccount::deposit()’ member function declared in class ‘savingsAccount’
void savingsAccount::deposit()
^
classes.hpp:105:31: error: no ‘void savingsAccount::withdraw()’ member function declared in class ‘savingsAccount’
void savingsAccount::withdraw()
^
classes.hpp:130:31: error: no ‘void savingsAccount::display()’ member function declared in class ‘savingsAccount’
void savingsAccount:: display()
^
classes.hpp:181:30: error: no ‘void currentAccount::deposit()’ member function declared in class ‘currentAccount’
void currentAccount::deposit()
^
classes.hpp:190:31: error: no ‘void currentAccount::withdraw()’ member function declared in class ‘currentAccount’
void currentAccount::withdraw()
^
classes.hpp:220:31: error: no ‘void currentAccount::display()’ member function declared in class ‘currentAccount’
void currentAccount:: display()
#include<iostream>
#include<cstring>
#define MAX 50
#ifndef classes_h
#define classes_h
using namespace std;
class account
{
protected:
char name[MAX];
int accountNumber;
char type[MAX];
float balance;
float minBalance;
static int Customers;
public:
account();
account(char*,int);
void deposit();
void withdraw();
void display();
int getAccountNumber();
static void numberOfCustomers();
};
account::account(char* name, int accountNumber)
{
strcpy(this->name,name);
this->accountNumber=accountNumber;
//strcpy(this->type,type);
this->balance=0;
Customers++;
}
int account::Customers=0;
void account ::numberOfCustomers()
{
cout<<"Total number of customer-------->"<<Customers;
}
void account::display()
{
}
/********************************
//Savings Account class
********************************/
class savingsAccount: public account
{
protected:
float minBalance;
// float rate;
public:
savingsAccount();
savingsAccount(char*,int);
savingsAccount(account&); //Copy Constructor
/* void deposit(); //user
void withdraw(); //user
void display(); //user
*/ int getAccountNumber();
};
savingsAccount::savingsAccount(char* name, int accountNumber):account(name,accountNumber)
{
minBalance=0;
strcpy(type,"savings");
}
savingsAccount::savingsAccount(account& tp):account(tp)
{
minBalance=0;
strcpy(type,"savings");
}
int savingsAccount::getAccountNumber()
{
return accountNumber;
}
void savingsAccount::deposit()
{
float amount;
cout<<"Enter the amount needs to be deposited"<<endl;
cin >> amount;
balance=balance+amount;
}
void savingsAccount::withdraw()
{
float amount ;
if(balance ==0)
{
cout<<"Account balance is Nil"<<endl;
return;
}
cout<<"Enter the amount yout would like to withdraw"<<endl;
while(1)
{
cin>>amount;
if(balance-amount<0)
{
cout<<"insufficient funds, try some less amount\n";
}
else
{
balance=balance-amount;
return ;
}
}
}
void savingsAccount:: display()
{
cout<<"Account Number"<<accountNumber<<endl;
cout<<"Name-->"<<name<<endl;
cout<<"Accounttype-->Savings"<<endl;
cout<<"Balance-->"<<balance<<endl;
cout<<"Minimum Balance -->"<<minBalance;
}
/***********************************
//Current Account class
************************************/
class currentAccount: public account
{
protected:
float minBalance;
public:
currentAccount();
currentAccount(char*,int);
currentAccount(account&);
/* void deposit();
void withdraw();
void display();
*/ int getAccountNumber();
};
/*
currentAccount::currentAccount(char* name, int accountNumber):account((char*)name,accountNumber,"current account")
{
minBalance=1000;
balance=1000;
}
*/
currentAccount::currentAccount(char* name, int accountNumber):account(name,accountNumber)
{
minBalance=0;
strcpy(type,"Current");
}
currentAccount::currentAccount(account& tp):account(tp)
{
minBalance=0;
strcpy(type,"Current");
}
void currentAccount::deposit()
{
float amount;
cout<<"Enter the amount needs to be deposited"<<endl;
cin >> amount;
balance=balance+amount;
}
void currentAccount::withdraw()
{
float amount ;
if(balance ==0)
{
cout<<"Account balance is Nil"<<endl;
return;
}
cout<<"Enter the amount yout would like to withdraw"<<endl;
while(1)
{
cin>>amount;
if(balance-amount<0)
{
cout<<"insufficient funds, try some less amount\n";
}
else
{
balance=balance-amount;
return ;
}
}
if(balance-amount<1000)
{
cout<<"Please keep the balance above minimum balance ";
}
}
void currentAccount:: display()
{
cout<<"Account Number"<<accountNumber<<endl;
cout<<"Name-->"<<name<<endl;
cout<<"Accounttype-->Current Account"<<endl;
cout<<"Balance-->"<<balance<<endl;
cout<<"Minimum Balance -->"<<minBalance;
}
int currentAccount::getAccountNumber()
{
return accountNumber;
}
#endif
When you do
void savingsAccount:: display(){/* rest here */}
you are telling the compiler to implement the definition of a member function called savingsAccount::display(). However you don't specify that you have this member function in your derived class declarations. Since you overloaded it, you need to add its signature to the derived classes, like
class savingsAccount: public account
{
/* virtual */ void display() /* override */; // probably you want this virtual in the base class
// the rest
};
otherwise the compiler only knows that there exists a base version, i.e. account::display(). So the compiler is indeed right telling you that there is no savingsAccount::display() member function, as you only have account::display(), i.e. the member function of the base class.
Your whole issue can be simplified to
struct X
{
void f();
};
struct Y: X
{
// void f();
};
// error if you don't add the signature in Y,
// there is no Y::f(), only the X::f() inherited part
void Y::f(){}
int main(){}
Live on Coliru
PS: You probably want to make those functions virtual too (and also add const to the ones that don't modify your member variables), so you have proper overriding, otherwise your derived member won't behave as you want when you have a class hierarchy controlled by a pointer-to-base.
PSS: put
#ifndef classes_h
#define classes_h
at the very beginning of your header, before any #include.

Implementing a constructor for a derived class in a .cpp?

My question is very beginner, and yes I have looked it up extensively, but when I do the things I've found online Xcode gives me errors.
Basically, I'm just curious how to implement a constructor for a derived class. My class is called "Sensor" and the derived classes are digitalSensor and analogSensor.
Here's my sensor.h:
#ifndef __Program_6__sensor__
#define __Program_6__sensor__
#include <iostream>
class sensor {
char* SensorName;
float energyDraw;
int functioning;
int onoff;
public:
sensor(char*n, float pc);
virtual void print();
void setOK(int K);
int getOK();
void setOnOff(int n);
int getOnOff();
};
//---------
class digitalSensor : public sensor {
int reading;
public:
digitalSensor(char*n, float pc);
virtual void print();
void setCurrentReading(int r);
int getCurrentReading();
};
class analogSensor : public sensor {
int Reading;
int minRead;
int maxRead;
public:
analogSensor(char *n, float pc, int mm, int mx);
virtual void print();
void setCurrentReading(int r);
int getCurrentReading();
};
#endif /* defined(__Program_6__sensor__) */
And here's my sensor.cpp, you can see the beginnings of my digitalSensor work at the bottom.
#include "sensor.h"
#include "definitions.h"
using namespace std;
//--------SENSOR CLASS------------//
sensor::sensor(char *n, float pc) {
SensorName = (char*)malloc(strlen(n)+1);
energyDraw = pc;
functioning = WORKING;
onoff = OFF;
}
void sensor::print() {
cout << " Sensor: " << SensorName;
cout << " Power Consumption: " << energyDraw;
if (functioning == WORKING) {
cout << "\nSensor is functioning correctly\n";
if (onoff == ON) {
cout << "Sensor is On";
}
if (onoff == OFF) {
cout << "Sensor is Off";
}
}
if (functioning == NOTWORKING) {
cout << "Sensor is not functioning correctly";
}
}
void sensor::setOK(int k) {
functioning = k;
}
int sensor::getOK() {
return functioning;
}
void sensor::setOnOff(int n) {
onoff = n;
}
int sensor::getOnOff() {
return onoff;
}
//---------------------------------//
//*********DIGITAL SENSOR**********//
sensor digitalSensor::digitalSensor(char *n, float pc) {
}
In a nutshell: I need to make a constructor function for the digital sensor class. What am I missing, how do I do that? Thanks in advance for any help or knowledge on this!
Implement its constructor like this:
digitalSensor::digitalSensor(char*n, float pc) : sensor(n, pc)
{
}
As you can see, it doesn't return anything and it calls its parent's constructor.
But you're doing this which is wrong:
sensor digitalSensor::digitalSensor(char *n, float pc) {
^^^^^^ constructors shall not return anything
}
You should call your base class constructor at the derived class's member initialization list.
For example:
class digitalSensor : public sensor {
int reading;
public:
digitalSensor(char*n, float pc): sensor(n, pc), reading(0){}
virtual void print();
void setCurrentReading(int r);
int getCurrentReading();
};
This defines the digitalSensor constructor inline. You can also define it with scope resolution operator outside class:
digitalSensor::digitalSensor(char*n, float pc):sensor(n, pc), reading(0){}
//^^Note that constructor of a class does not have any return type
It really depends on how your base class constructors are provided. But this could be one way to do it. You may find Initializing base classes and members useful.