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.
Related
The code is really simple (but I am a newbie so I have no idea what I am doing wrong) :
#include<iostream>
#include<string>
void PrintEntity(Entity* e);
class Entity
{
public:
int x,y;
Entity(int x, int y)
{
Entity* e= this;
e-> x=x;
this->y=y;
PrintEntity(this);
}
};
void PrintEntity(Entity* e)
{
// *Do stuff*
}
int main()
{
return 0;
}
My understanding of the error is that I cannot declare the function PrintEntity before of
the class Entity. But even if I would declare the function below the class it would be a problem since in the Constructor I am calling the function PrintEntity.
So I am quite stuck . Can anybody explain to me what I am doing wrong please?
Declare the function before the class definition like
void PrintEntity( class Entity* e);
using the elaborated type specifier.
Otherwise the compiler does not know what is Entity.
The compiler reads your file from the top down.
When it encounters void PrintEntity(Entity * e);, it must determine whether Entity * e is a formal parameter (making this a function declaration) or a multiplication (making this a variable declaration with initialiser).
Since the compiler is completely unaware of a type called "Entity", it decides that this must be a variable declaration, and a variable cannot have type void.
The solution is to declare the class before the function prototype, either separately:
class Entity;
void PrintEntity(Entity* e);
or directly in the function declaration:
void PrintEntity(class Entity* e);
This code compiles (Using GCC / C++11):
void doStuff_HELPER(int a) { /**/ }
class SomeClass{
public:
void doStuff() {doStuff_HELPER( 10);}
};
This doesn't:
void doStuff(int a) { /**/ }
class SomeClass{
public:
void doStuff() {doStuff( 10);}
};
It doesn't say it's ambiguous or it can't be overloaded or anything it just says: "no matching function SomeClass::doStuff(int)", "candidate: void SomeClass::doStuff()". Is this the correct behavior? What does the standard say about this?
(Also, what is the best practice for such helper functions? Should they be put into a separate namespace maybe?)
Call it explicitly specifying scope: ::doStuff(10);
You should use the Scope Resolution Operator to resolve this. Using ::doStuff(10) instead of doStuff(10) tells the compiler to look in the global namespace to resolve the name collision.
#include <iostream>
using namespace std;
class CClass
{
private:
friend class CFriend;
static void privateFunc(){std::cout << "privateFunc" << std::endl;};
};
class CFriend
{
public:
void privateFunc(){privateFunc();};
};
int main(int argc, char* argv[])
{
CFriend b;
b.privateFunc();
return 0;
}
This code compiles, but using the gcc-compiler or http://www.ideone.com/ the program crashes. Is that a compiler error or do I need to understand more about friend classes?
You've created infinite recursion:
void privateFunc(){privateFunc();};
Use instead:
void privateFunc(){CClass::privateFunc();};
There's nothing wrong with friend declaration.
Infinite recursion in your object, creating a Stack Overflow !!!
You must explicitely call your friend class :
void privateFunc(){CClass::privateFunc();};
You have the function called privateFunc() in CFriend class as well. This means when inside that function you call privateFunc() it will call itself (how should it know you mean the other class) thus entering a recursive infinite loop.
You mean
void privateFunc()
{
CClass::privateFunc();
}
using CClass:: to specify completely the name of the function you mean.
It is crashing because of stack overflow you would beed scope resolution to call static function
class CFriend
{
public:
void privateFunc(){CClass::privateFunc();};
};
You have a stack overflow from an infinitely recursive function. CFriend::privateFunc is calling itself. Change it to void privateFunc() {CClass::privateFunc();}
Scope distinctions, public, private, protected and friend, have not runtime consequences at all. They are strictly for the compilier to decide what is legal or not. You could #define private public and the resulting executable wouldn't change.
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.
I was trying to write up a class in c++, and I came across a rather odd problem: calling outside functions inside of a class that have the same name as the class. It's kinda confusing, so here's an example:
void A(char* D) {
printf(D);
}
class A
{
public:
A(int B);
void C();
};
A::A(int B) {
// something here
}
void A::C() {
A("Hello, World.");
}
The compiler complains at the second to last line that it can't find a function A(char*), because it is inside the class, and the constructor has the same name as the function. I could write another function outside, like:
ousideA(char* D) {
A(D);
}
And then call outsideA inside of A::C, but this seems like a silly solution to the problem. Anyone know of a more proper way to solve this?
::A("Hello, world.");
should work fine. Basically it is saying "use the A found in the global namespace"
Use the scope resolution operator :: to access the name from the global scope:
void A::C() {
::A("Hello, world.");
}
I suggest you use namespaces. Put your class in a different namespace than the function.
namespace my_namespace1
{
void A() {}
}
namespace my_namespace2
{
struct A {};
}
int main()
{
my_namespace1::A();
my_namespace2::A my_a;
}
Of course, the real question is, why do you have a class and a function with a different name? A good easy rule is to make classes named WithABeginningCapitalLetter and functions withoutOne. Then you will never have this problem. Of course, the STL doesn't do this...