The following example is obviously wrong, but I would like to know if it possible to achieve something like the following
extern int return_value();
class A {
private:
int k = 1;
public:
friend int return_value();
};
int return_value()
{
return k;
}
I know I can't do the following without passing an instance of class A into function return_value() as return_value(A &a) then accessing the variable as a.k
note the function return_value() is an example. I would like to know if there is a way within the scope of the C++ language to allow direct access to variables in non-member function bodies
AFAIK there are only two ways to access members of a class (for non-member functions).
Either through an instance as you described.
Or without the instance iff the member is declared as a static member. That is, it has the same value for all objects of that class, and can be accessed directly using the class scope operator.
Ofcourse this is assuming the scope permits the function to access the class members.
Related
In my current project I am trying to pass a private member function as parameter to another function. In my code, the other function is a member function of a different class, but for keeping it simple, here it is a free function.
void outside_function(std::function<void(int)> func) {
// do something with func
}
class MyClass {
public:
void run();
private:
bool my_func(double); // defined in source file
};
Now, from inside run I want to put my_func into outside_function as argument. Since the signature of run does not fit the requirements for the parameter, I cannot simply pass it. Using the adapter pattern was my first try, which was when I was reminded that member functions implicitly take the this pointer as first argument. This answer suggests using a lambda expression, which is what I did.
void MyClass::run() {
outside_function([this](int a) -> void {
double d = static_cast<double>(a);
this->my_func(d);
});
}
Why does this work? From my point of understanding, outside_function does not have access to my_func. Why don't I have to make my_func public first? Is it something the compiler does or some C++ rule I don't know?
Additionally, are there any catches to this approach that might break my code?
private access specifier only restrict an object name to be visible (it cannot be looked up) outside the class. The object itself is like any other member.
[class.access]/1
A member of a class can be
(1.1) private; that is, its name can be used only by members and friends of the class in which it is declared.
(1.2) protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).
(1.3) public; that is, its name can be used anywhere without access restriction.
outside_function never accesses the member (it only knows the type of the func parameter and can't possibly care about how it's defined) -- only the lambda function does.
Since you're defining the lambda function inside MyClass, you can access all the private names within it.
outside_function calls the provided function, but if you weren't allowed to call a function that uses any private members, you couldn't do much.
I have public member functions which are calling private member function. I want to limit the scope of the private member function within the file where definition of private member function is available. In C, I used static before the function name to limit its scope within the file, how do I achieve it in C++.
class Base
{
public:
void XYZ1(void);
void XYZ2(void);
private:
void fun(void);
};
void Base::XYZ1(void)
{
fun();
}
void Base::fun(void)
{
// do something;
}
Now if the member function XYZ2 is defined in some other .cpp file , it should not be allowed to call fun() from it. Basically restrict the fun() function to file scope.
In a1.cpp
void Base::XYZ2(void)
{
fun();// this should result in some error saying fun() is not defined in its scope.
}
I want to limit the scope of the private member function within the file where definition of private member function is available.
A private member function cannot be used by another class or function unless they are granted friend-ship by the class. In that sense, the scope in which the function can be called is already limited.
Having said that, any member function of the class or any class or function that has been granted friend-ship by the class will be able to call the private member function.
The only way to prevent that function from being called outside the file in which it is defined is to make it a non-member static function in the .cpp file. or put it in an anonymous namespace in the .cpp file.
Now if the member function XYZ2 is defined in some other .cpp file ,
it should not be allowed to call fun() from it. Basically restrict the
fun() function to file scope. In a1.cpp
You can put the function in an anonymous namespace (in the cpp file where used). The linkage will become internal, and the name won't be available for access from any other file. One can get the same effect when making the function static (in the cpp file).
If you need to access internal/private members, you could use a nested class who's implementation is defined in the associated cpp file:
//h
class Nesting
{
//...
private:
struct MyPrivateFunctions;
};
//cpp
struct Nesting::MyPrivateFunctions
{
static void f1(Nesting& this);
static void f2(Nesting& this);
//etc...
};
I've passed Nesting as parameter that MyPrivateFunctions may access its private members (since it is nested, this is permitted).
Note that this is very similar to the Impl trick mentioned elsewhere, but it also allows independent member function definitions in other units, and it does not need instantiation.
Most people are suggesting you to use anonymous namespace in C++. But, this would only be feasible if you wanted to do something like, declaring a global variable/function which is supposed to be used strictly inside the file under which it is defined.
We cannot use namespace within the class as per C++ standards, for which you may want to take a look at this discussion: Why can't we declare a namespace within a class?
I used static before the function name to limit its scope within the file.
This worked for you but the understanding here is wrong as static was never intended to be used as scope specifier, its a storage specifier and its lifetime is throughout the program life. You can still access the static variable from other files in several ways, however the compiler here does not provide an externally visible linker symbol and thus cannot be accessed by other translation units / files.
As per the public member functions are concerned they should be allowed to use this private function from whichever file it is defined in. So that the relation between the class member functions are not destroyed. I suppose you would now stop treating static as scope specifier :)
Or you can use the good old Impl- trick if you do not want to show the "hidden" functions of a class to the outside. Private functions are still listed in the header file, after all.
// Foo.h
class FooImpl; // forward declearation
class Foo
{
FooImpl *m_pImpl;
public:
Foo(); // Default constructor (and any other) create instance of FooImpl.
~Foo();
};
// Foo.cpp
class FooImpl
{
// members of hidden types, secrets, methods, ... anything you do not want to show to users of class Foo.
};
Foo::Foo() : m_pImpl(new FooImpl()) {}
Foo::~Foo()
{
delete m_pImpl; m_pImpl = nullptr;
}
As can be seen, with the impl trick you cannot only hide functions, but also data members of a class and type dependencies which would be incurred if the members were part of Foo class.
A way to solve this problem is by using a so called 'facade'. Basically, you have two classes: The first class has the private method which you want to hide, where as the second class implements a wrapper which just provides the methods you want to be accessible. The second class wraps an instance of the first. That's how the whole trick works.
https://en.wikipedia.org/wiki/Facade_pattern
I'm fairly inexperienced with C++ and I'm trying to understand what this code does.
template <typename T>
class System : public BaseSystem
{
[..]
private:
static SystemType sysType;
};
Outside the class definition there is something like this:
template <typename T>
SystemType System<T>::sysType= IDGen<BaseSystem>::GenerateNextID();
Is this setting the sysType field in the System class to a new ID? But since the sysType field is private how is it able to access it? Also, why is the type included before the assignment?
If I wanted to change a field I would do something like field = newvalue; however this Foo field = newvalue; seems like it's creating a new field of type Foo and then assigning it.
Can anyone explain what is that line of code doing?
It is not an "assignment". It is the definition of the static data member sysType of your class. In your case the syntax contains quite a bit of template-related stuff, but the immediate matter in question has nothing to do with templates at all. A minimalistic example of the same thing might look as follows
class SomeClass {
...
static int i; // declaration of `SomeClass::i`
...
};
int SomeClass::i = 42; // definition of `SomeClass::i`
All static members of the class have to be defined somewhere (with some exceptions for constant integral members). What you have inside the class is a mere declaration.
So, one more time: every time you declare a static data member in your class, you will have to define it somewhere outside of the class, following the general One Definition Rule for data objects with external linkage, i.e. you have to define in your program once and only once.
In your case the definition includes an initializer. The = is a part of the initialization syntax. It has nothing to do with assignment.
The access protection does not come into play here at all. In this case you are not accessing a class member, you are defining it. Just like you define private member functions outside of the class, you define private static members outside of the class.
Is it not supposed for a friend function to be explicitly defined outside of a class ?
If so why can i declare a friend function inside a class definition just like any member function ?
What is this ?
Is it only OK with some operators such as < operator or is it applicable to all operators?
If it is applicable to all of them, Is there any disadvantage for doing this ?
Should it be avoided? If so why ?
class person
{
public:
bool operator<(int num)
{
return x < num ? true : false ;
}
bool operator<(person& p)
{
return x < p.x ? true : false ;
}
friend bool operator<(int num, person &p)
{
return p.x < num ? true : false ;
}
void setX(int num)
{
x = num;
}
private:
int x;
};
Update:
I am not asking for choosing non-member operator overloading or member operator overloading.
What i want to know is that :
Why we are permitted to move the definition of friend methods inside our class definition?.
Is it not violating any things? If it is not, Why would we have friends in first place?
We could simply define overloads as member functions ( I know the limitations of member functions ) But i am saying knowing this, Why isn't compiler complaining that I haven't defined friend function outside a class definition since it doesn't need to be inside of it (because of the class parameter it has)
So why are we allowed to define a friend function inside a class definition?
Is it not supposed for a friend function to be explicitly defined outside of a class ?
Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions, and like member inline functions they behave as though they were defined immediately after all class members have been seen but before the class scope is closed (the end of the class declaration). Friend functions that are defined inside class declarations are in the scope of the enclosing class.
quote
Is it only OK with some operators such as < operator or is it applicable to all operators?
It is best to try to avoid friend functions since they are opposite to what you are trying to do using a private class scope and mainly "hide" the variables. If all your functions are friend functions then what is the use of having private variables?
Still, there are some common operators which are often declared as friend functions, those are operator<< and operator>>
Alexandru Barbarosie answer is correct. It means that we can declare a friend function, which is not a member function, within a class. This can be nice to organize the code. I think an example can help to understand it in case it isn't clear.
#include <iostream>
class A {
public:
A(int val) : val(val) {}
// The following isn't a member function, it is a friend
// function declared inside the class and it has file scope
friend void draw (A &a) {
std::cout << "val: " << a.val << "\n";
}
private:
int val;
};
int main() {
A a(5);
draw(a); // outputs "val: 5"
//A::draw(a); // Error: 'draw' is not a member of 'A'
}
If you are creating a header-only class (which makes deployment vastly easier) then defining a friend function within the class is the only way to go since definitions can only appear in a single translation unit. The normal technique of include guards doesn't work since that only handles things like recursive inclusion.
This can be a big deal if you are trying to write standards-conformant code. For example, to implement the RandomNumberEngine named requirement from the C++ normative standard, it is necessary to provide operator<<. This has to be a friend to take a std::ostream& object as its first parameter (otherwise it will look like a normal, single parameter member function operator overload). Ordinarily the friend declaration would go in the class definition and and the function definition in a separate .cpp source file. But if you want a header-only implementation, it must be defined in the class to avoid multiple definition errors.
Because an operator needs to know details of the right-hand side of the expression in which is used, if it must access private data of the type which resides on that side, it needs to be friend with that class.
If you are trying to compare an int with a person, like in your example, choices are two:
you provide an implicit conversion from person to int so that < can use it without accessing any private field.
or you declare the operator as friend of person so that it can access x in the right-hand side of the comparison.
As Jack mentioned friend functions are required in places where access to private data is needed. There is also another purpose. This is related to types of inheritance. Only derived class and its friends can convert pointer to a private base to a derived type. So you might sometimes want to make some function a friend of derived class to allow this inside function body.
A .cpp file has a bunch of class definitions . One class has a private static member as follows:
class SomeClass:public SomeParentClass
{
private:
static int count;
};
and right after the class is defined, the count attribute to initialized to zero as follows:
int SomeClass::count = 0;
Coming from the Java/C# world I am having trouble understanding at which point is count initialized to zero? Is it when the SomeClass is instantiated? Also, the class definition has the count type to be int, why does the SomeClass::count has to have an int in front of it?
And my last question is, since the count attribute is private shouldn't its visibility be restricted when it is initialized outside the class definition?
Thanks
Static members of the class are initialized in arbitrary order upon your program's start-up
The static int count; in the class is a declaration of your static variable, while int SomeClass::count = 0; is its definition. All definitions in C++ require to specify a type.
The fact that the definition of the count appears to have occurred in the file scope, the actual scope of the SomeClass::count remains private, as declared.
Is it when the SomeClass is instantiated?
No, you can access it via SomeClass::count (assuming the function has rights to SomeClass's private members) before any instantiations. It's fully usable before you start making objects.
Why does the SomeClass::count has to have an int in front of it?
Well, because it's an int. Think of when you make function prototypes and definitions:
int func (int);
int func (int i) {return 1;} //you still need the int and (int i) here
func {return 1;} //NOT VALID - this is what count would be without int
Since the count attribute is private shouldn't its visibility be
restricted when it is initialized outside the class definition?
Static variable definition is an exception to access specifiers when defined in the normal manner, according to this answer.
The class static variable will behave as if it is initialized to 0 when the program starts. It is independent of class instantiation.
The C++ language requires a type before an identifier in a declaration.
The C++ syntax to initialize a class static variable makes it look like a global, but access to the variable is enforced during compilation.