class Base
{
private:
static int num;
public:
friend void setnum(Base obj);
};
void setnum(Base obj)
{
obj.num=4; /* Error */
}
A friend function is supposed to have access to all the private data of a class. what am i missing here? I cant seem to access the the static variable from the friend function.
Error from codepad--> In function
setnum(Base)': undefined reference to
Base::num'
Error from visual studio--> error LNK2001:
unresolved external symbol "private:
static int Base::num"
You only declared the static variable num. You must to define it:
class Base
{
private:
static int num;
public:
friend void setvals(Base obj);
};
// This must be in a .cpp
int Base::num;
void setvals(Base obj)
{
obj.num=4;
}
This code works.
Edit:
Actually you can implement the setvals() function as follows:
void setvals()
{
Base::num=4;
}
And at your Base class:
friend void setvals();
Because num is static.
Your free function is called setvals, but the Base's friend function is called setnum...
Besides you'll have to actually define the static variable, not just declare it.
Put:
int Base::num;
in a source file.
Different friends:
friend void setnum(Base obj);
// ^^^ Not the same as vals!
void setvals(Base obj)
In C++ it's not enough to declare a static variable in the .h; you must also define it explicitly in a .cpp. You must add in the .cpp of the implementation
int Base::num;
What you got was a linker error because of this missing variable definition.
Static variables don't belong to any particular instance of a class. Instead you may access them with a class name as Base::num to improve readability. Also, your friend function definition has a different signature than the one you declared.
Related
I am trying to define a function member of a class Extraction FRIEND with a class Descripteur, but when I compile I get the following error :
*Descripteurs.h:24:57: error: invalid use of incomplete type ‘class Extraction’ friend
void Extraction::globalSet(Descripteurs document);
Descripteurs.h:19:7: error: forward declaration of ‘class Extraction’
class Extraction;*
given by the code :
//in Extraction.h
#include "Descripteurs.h"
class Extraction {
public:
Extraction(Descripteurs document);
void globalSet(Descripteurs document);
protected:
int m_value;
}
// in Extraction.cpp
#include "Extraction.h"
Extraction::Extraction(Descripteurs document){
this->globalSet(document);
}
void Extraction::globalSet(Descripteurs document){
this->m_value = document.m_nbMot; //this is why I need a friend function
cout << this->m_value << endl;
}
//in Descripteur.h
class Extraction; //forward declaration, is there a problem with this ?
class Descripteurs {
public:
friend void Extraction::globalSet(Descripteurs document);
protected:
int m_value;
};
I guess the trouble comes from the fact my classes are imbricated, because Extraction uses Descripteurs and Descripteurs has to know Exctraction to deal with the friend function. I thought the forward declaration was a solution, as explained in how comeforward or c++ friend namespace but I could not find documentation that deal with at the same time friend function, imbricated class and separated files.
and if i remove "Class Extraction;" I get as expected the following error :
‘Extraction’ has not been declared
friend void Extraction::globalSet(Descripteurs document);
friend function over accessor (get functions) is a choice : I don't want to make the attributes accessible from anywhere (in situation the function should take several complex attributes, and not just an int).
Can anyone tell me if I need to add some pieces of code or if there is no way to do this without using accessors ?
Any Help will be welcomed
Thanks
Alexis
Unfortunately, you can't declare a member function of a forward-declared class as friend. See this question for possible workarounds.
I have a method inside the Foo class that needs to call the free floating function freeFloat. However, calling it results in a out of scope error.
Foo.cpp: In member function ‘virtual bool Foo::method()’:
Foo.cpp:351:24: error: ‘freeFloat’ was not declared in this scope
freeFloat();
The structure of the code looks something like this:
class Foo {
public:
virtual void method() {
freeFloat();
}
};
int main(){
}
bool freeFloat(){
}
Can this be done? If so, is it considered poor practice or in most cases OK? Is there a better placement for each method?
The function shall be declared before the class definition if it refers to the function.
Any name in C++ shall be declared before its using.
You need to declare the function before calling it....
bool freeFloat();
class Foo {
public:
virtual void method() {
freeFloat();
}
};
int main(){
}
bool freeFloat(){
}
You need to declare freeFloat before you can call it. Either move the function definition to the top or add:
bool freeFloat();
to the top.
I have the following header:
class MyClass {
private:
static void (*OnRequest)();
static void (*OnReceive)(int numBytes);
public:
MyClass();
static void SetOnReceive(void (*function)(int));
static void SetOnRequest(void (*function)(void));
};
void NonClassFunction();
and the following declaration:
#include "MyClass.h"
MyClass::MyClass() {
...
}
void MyClass::SetOnReceive(void (*function)(int) ) {
OnReceive = function;
}
void MyClass::SetOnRequest( void (*function)(void) ) {
OnRequest = function;
}
void NonClassFunction() {
MyClass::OnRequest();
}
The code compiles fine but I get the following errors when I link:
unresolved symbol MyClass::OnReceive, first referenced in ./src/MyClass.obj
unresolved symbol MyClass::OnRequest, first referenced in ./src/MyClass.obj
I need OnRequest and OnReceive to function like a callback through NonClassFunction(). The NonClassFunction is being called by an interrupt so there is a bit of object oriented mangling going on here. MyClass is designed to be inherited. Ideally I would like OnRequest and OnReceive to be virtual but you cannot make static methods virtual.
Those are linker error, which means the members are not defined. They're only declared.
The pointer members are static members, so they need definition, which is outside the class.
Do this in the .cpp file:
void (*MyClass::OnRequest)();
void (*MyClass::OnReceive)(int);
These are definitions, and what you've written in the class are only declarations.
Note the position of * in the above definitions. A slight mistake such as these:
void (MyClass::*OnRequest)(); //notice the difference
void (MyClass::*OnReceive)(int); //notice the difference
would change the meaning completely! Now these are pointers-to-non-static-member-function. So know the difference and be careful. :-)
These two variables in your header:
static void (*OnRequest)();
static void (*OnReceive)(int numBytes);
Have not been defined.
Define them in your cpp file.
void (*MyClass::OnRequest)();
void (*MyClass::OnReceive)(int);
You provided the declarations of the function pointers, but not the definition. Add this to a single cpp file:
void (*MyClass::OnRequest)();
void (*MyClass::OnReceive)(int);
i asked the same question recently
how-to-send-a-message-to-the-class-that-created-the-object
enemies_array[0].enemy = new Enemy(this,&Game::EnemyEvent);
typedef void (Game::*ChangeFunc)(DWORD &)
Class Enemy
{
private:
ChangeFunc iChange;
Game *pGame;
}:
Enemy(Game *pCreatorGame, ChangeFunc iChangeHandler )
{
iChange = iChangeHandler;
pGame = pCreatorGame;
}
void Enemy::Draw(D3DGraphics& gfx)
{
(pGame->*iChange)(this->dwThreadID);
I have two classes, one and two, each having a friend member function with an pointer to the other. The first header file is as per below:
#ifndef FIRSTCLASS_H
#define FIRSTCLASS_H
class two;
class one {
private:
int one_data;
public:
friend void second_data (two *);
};
#endif
The second header file looks like this:
#ifndef SECONDCLASS_H
#define SECONDCLASS_H
class one;
class two {
private:
int two_data;
public:
friend void first_data (one *);
};
#endif
The actual functions are in a third .cpp file. I wrote the functions with appropriate class qualifier, it gives an compilation error. I am using g++. The functions are as follows:
#include "firstclass.h"
#include "secondclass.h"
void two::first_data (one * class1) {
}
void one::second_data (two * class2) {
}
The errors are as followa:
error:no ‘void two::first_data (one*)’ member function declared in class ‘two’
error: no ‘void one::second_data(two*)’ member function declared in class ‘one’
When I drop the class qualifier before the function name, the code compiles. The modified functions are as follows:
void first_data(one * class1) {
}
void second_data(two * class2) {
}
I am new to c++ and I am not sure if I am doing anything wrong in the first case. Please enlighten me.
What you declare is freestanding functions as friends of your classes.
They are not really members of any class.
friend void first_data (one *);
declares a freestanding function first_data as friend of your class, it does not mean first_data is a member function of your class. Hence when you define the function in cpp file the compiler complains that the function was never declared.
Also,
void two::first_data (one * class1){}
Returntype ClassName ScopeResolution FunctionSignature
two:: tells compiler the functions belongs to this particular class, it is not namespace specification, it is class qualification.
That's not a namespace, that's a class qualifier.
void two::first_data (one * class1) {
}
defines the method first_data from class two.
However, you declared as friend the free function first_data:
friend void first_data (one *);
which is not the same. If you want free functions as friends, use the friend declaration you already have. If not, you can declare methods as friends similary:
friend void two::first_data (one *);
I'm new with C++, and I got this linker error,
LNK2001: unresolved external symbol "private: static class DebugLog Singleton::instance" (?instance#?$Singleton#VDebugLog####0VDebugLog##A)
And here is the problematic codes:
template<typename T>
class Singleton {
public:
static T& getInstance() {
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> {
public:
void doNothing() {}
};
void main() {
DebugLog::getInstance().doNothing();
}
Could anybody tell me how I can fix that linker error without losing the Singleton inheritance in DebugLog?
Thank you.
You missed:
template<typename T>
T Singleton<T>::instance;
Insert those lines after your class definition.
In order to initialize a static data-member we must include a formal
definition outside the class, in the global scope.
For more information read this link (Section: Static members)
You need to actually define an instance of the static variable DebugLog Singleton::instance somewhere in your code, you just declared that it exists somewhere, but never actually created it to really exist. The linker is looking for it.
Here's some examples of how to do it right.