Why does friend class crash on static function call? - c++

#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.

Related

Can't use helper function with same name as member function

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.

Set reference of function to non-static function from other c++ file

I'm trying to set a reference of a non-static function in c++. The function I'm referencing is not from the same c++ file, and I get and error saying :
Cannot create a non-constant pointer to member function.
Main.cpp
#include <iostream>
#include "Test.hpp"
class testClass {
public:
void (*update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &t.update; //This is where the error occurs
return 0;
}
Test.hpp
#ifndef Test_hpp
#define Test_hpp
#include <stdio.h>
class test {
public:
void update() {
//Do something
}
};
#endif /* Test_hpp */
My question is how do you do this without setting update in test class to static?
static void update() {
//Do something
}
Using this code it works, but like I've stated I do not want this functiont to be static.
EDIT :
Because I'm stupid I failed to mention that the class test should be able to be different. Also to the answers I got already I learned that tc.update = &t.update; is wrong.
For Example :
#include <iostream>
#include "Test.hpp"
#include "anotherTestClass.hpp"
//I do not want to use templates if possible
class testClass {
public:
void (*update)(void);
};
int main() {
testClass tc;
test t;
tc.update = &test.update; //I know this is wrong now.
testClass tc2;
anotherTestClass atc;
tc2.update = &atc.update;
//p.s. I'm bad with c++
}
And the error i get now is.
Assigned to 'void (*)()' from incompatible type 'void (test::*)()'
One more thing is I'm using XCode to program, which I believe uses LLVM-GCC 4.2 as the compiler.
class test {
public:
void update() {
//Do something
}
};
class testClass {
public:
void (test::* update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &test::update;
return 0;
}
Your approach is essentially wrong.
Member Function Pointers.
The member in the testClass:
void (*update) (void);
is a function pointer, which is different to a method function pointer. That why in order to compile you should switch to a static method (which is essentially a "normal" function).
A method function pointer should containt the static information about the class the method belongs.
Practically the right way is:
void (test::* ptr_method)(void); // a member pointer to test class
In that way the variable named ptr_method is a method of the class test pointer.
Then,
Get the Address of a method.
Your statement:
tc.update = &t.update; //This is where the error occurs
is simply wrong. The address of a class method is something which is not related with the object of that class.
You can obtain the address of a method with the syntax:
&CLASS_NAME::METHOD_NAME;
Indeed, that statement should be something like:
tc.update = &test::update;
Additional suggestions.
Call a method by means of a method pointer.
Once you have a method pointer it is not so immediate to call the method associated with it.
As I said before, the address of the method is not related with the object of that class, so if you want to call the method you need to provide to the compiler the information about the object on which the method has to be called.
The syntax is something like:
(OBJECT.*METHOD_POINTER)(ARGS...);
Here, I propose a simple demo which shows all what I've just said.

Member is inaccessible

class Example{
public:
friend void Clone::f(Example);
Example(){
x = 10;
}
private:
int x;
};
class Clone{
public:
void f(Example ex){
std::cout << ex.x;
}
};
When I write f as a normal function, the program compiles successful. However, when I write f as a class member, this error occurs.
Screenshot:
The error you're seeing is not a root-cause compilation error. It is an artifact of a different problem. You're friending to a member function of a class the compiler has no earthly clue even exists yet,much less exists with that specific member.
A friend declaration of a non-member function has the advantage where it also acts as a prototype declaration. Such is not the case for a member function. The compiler must know that (a) the class exists, and (b) the member exists.
Compiling your original code (I use clang++ v3.6), the following errors are actually reported:
main.cpp:6:17: Use of undeclared identifier 'Clone'
main.cpp:17:25: 'x' is a private member of 'Example'
The former is a direct cause of the latter. But doing this instead:
#include <iostream>
#include <string>
class Example;
class Clone
{
public:
void f(Example);
};
class Example
{
public:
friend void Clone::f(Example);
Example()
{
x = 10;
}
private:
int x;
};
void Clone::f(Example ex)
{
std::cout << ex.x;
};
int main()
{
Clone c;
Example e;
c.f(e);
}
Output
10
This does the following:
Forward declares Example
Declares Clone, but does not implement Clone::f (yet)
Declares Example, thereby making x known to the compiler.
Friends Clone::f to Example
Implements Clone::f
At each stage we provide what the compiler needs to continue on.
Best of luck.

Calling a free floating function within a class

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.

C++ - Calling a function inside a class with the same name as the class

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...