Usage of local class in C++ function - c++

I see some usage of internal struct in c++ function.
There is a common interface IBase. Here is the draft code.
class IBase
{
virtual Method()=0;
}
vector<IBase*> baseList;
Then a function defined an internal class based on that IBase, and then push the internal class object into the baseList.
void func()
{
struct Object : public IBase
{
virtual Method()
{
// Method of Object in func
}
}
IBase* base = new Object();
baseList->push(base);
}
It seems a strange usage, but a nice implementation of message/event creation pattern.
Other threads maybe use this baseList to handle the incoming event.
What's the scope of internal struct of "struct Object"? It's very interesting. Is there some documents talking about this?

What's the scope of internal struct of "struct Object"?
The scope of the local classes is the function in which they're defined.But that isn't interesting in itself.
What makes local classes interesting is that if they implement some interface (like your code does), then you can create instances of it (using new) and return them (for example, as std::vector<IBase*>), thereby making the implementation accessible through the base class pointer even outside the function.
Some other facts about local classes:
They cannot define static member variables.
They cannot access nonstatic "automatic" local variables of the enclosing function. But they can access the static variables.
They can be used in template functions.
If they are defined inside a template function, then they can use the template parameters of the enclosing function.
Local classes are final, that means users outside the function cannot derive from local class to function. Without local classes, you'd have to add an unnamed namespace in separate translation unit.
Local classes are used to create trampoline functions usually known as thunks.
EDIT
Some references from the Standard (2003)
9.8 Local class declarations [class.local]
\1. A class can be defined within a function definition; such a class is
called a local class. The name of a
local class is local to its enclosing
scope. The local class is in the scope
of the enclosing scope, and has the
same access to names outside the
function as does the enclosing
function. Declarations in a local
class can use only type names, static
variables, extern variables and
functions, and enumerators from the
enclosing scope.
[Example:
int x;
void f()
{
static int s ;
int x;
extern int g();
struct local {
int g() { return x; } // error: x is auto
int h() { return s; } // OK
int k() { return ::x; } // OK
int l() { return g(); } // OK
};
// ...
}
local* p = 0; // error: local not in scope
—end example]
\2. An enclosing function has no special access to members of the local
class; it obeys the usual access rules
(clause 11). Member functions of a
local class shall be defined within
their class definition, if they are
defined at all.
\3. If class X is a local class a nested class Y may be declared in
class X and later defined in the
definition of class X or be later
defined in the same scope as the
definition of class X. A class nested
within a local class is a local class.
\4. A local class shall not have static data members.

\4. A local class shall not have static data members.
BUT you can do this, inside of a local class
int GetCount()
{
class _local
{
public:
static int Count(int count = std::numeric_limits<int>::max())
{
static int count_ = 0;
if (count != std::numeric_limits<int>::max()) count_ = count;
return count_;
}
static float Operation(float a, float b)
{
_local::Count(_local::Count() + 1);
return a;
}
};
_local::Count(0);
CALLBACK( _local::Operation);
return _local::Count();
}
_local::Count can be used to read and write the otherwise static variable
-aydin

This is normal C++. The scope of struct Object is only the function func. However, you can still use objects of this type without knowing which concrete type they are, since they inherit from IBase. This is used to encapsulate implementation.

A very interesting use of a local class is presented by Jason Turner in his CppCon talk focused on programming of Commodore 64 game in C++17. He shows how to use the RAII principle on the function level.
He basically establishes invariants in the constructor of a local class in a function returning an instance of this class. The invariants duration is thusly controlled by the lifetime of the returned object. It is quite similar to what RAII wrappers like std::lock do, just slightly different.
You can see the appropriate part here, but I love his performance and recommend to see it all the way through.

Related

Defining static data member of abstract class template inside constructor

I've come across an exam question with this abstract class template definition:
template <class MusicPlayer>
class SongAbstract {
protected:
unsigned long unique_id;
public:
SongAbstract() {
static unsigned long counter = 0;
unique_id = (counter++);
}
int play() const { return MusicPlayer::play(this->unique_id); }
void stop() const { MusicPlayer::stop(); }
unsigned long get_id() const { return unique_id; }
protected:
virtual void print_info(ostream& os) const = 0;
};
The question in the exam is as follows:
"From the code above it follows that an implementation of the class MusicPlayer is required.
Write a declaration for a class called AndroidMusicPlayer so that the program will run."
The official solution:
class AndroidMusicPlayer {
public:
static int play(unsigned long id);
static void stop();
};
I'm having trouble understanding what the constructor does and would very much appreciate it if someone could explain the following:
What is the purpose of defining the static data member inside the constructor?
Why are the methods in AndroidMusicPlayer declared as static? They access data member
"unique_id," which is not static.
What is the purpose of defining the static data member inside the constructor?
The counter variable inside the SongAbstract constructor is not a member of the class – it is a local variable. Being declared as static means that its value will be initialized (to zero) only once during the entire program run (the first time that constructor is called). That value is then incremented on each and every call, causing the actual member variable (unique_id) to be assigned a different value for each object constructed.
Why are the methods in AndroidMusicPlayer declared as static? They access data member "unique_id," which is not static.
Not quite! They are passed the value of the containing class member variable (well, one is); the confusion here is, perhaps, that the two functions have the same names as member functions of the containing class. The two functions of that SongAbstract class call the functions of the same name in the passed MusicPlayer class; those latter functions have to be static, because there is no instance of their class declared as a member of SongAbstract – hence why we pass the unique_id as an argument.
(The syntax MusicPlayer::stop() is here used to call a static class member; similar syntax can be used to call a non-static member, but only if the class is a base class of that from which it is being called.)

double colon for instance variables in c++

I have always been under the impression that <class>::<variable> is for accessing static members. However, I am surprised to find out that the following compiles just fine. (I would have used this-> as shown in the inline comment.)
Further investigation on Google/StackOverflow doesn't show anything pertinent to this behavior, I wonder if anyone could shed some light on this.
class Test {
private:
int x;
public:
void set_x(int x) {
// this->x = x;
Test::x = x;
}
};
int main(int argc, char *argv[])
{
return 0;
}
ENV: clang version 7.0.0- (trunk)
The :: is the scope-resolution operator and can be use to specify which of a number of symbols of the same name but different but visible scope the reference refers to.
Either scope-resolution or this-> may be used in this example, but scope-resolution itself has more general applicability within the language.
http://eel.is/c++draft/basic.lookup.qual#class.qual
If the nested-name-specifier of a qualified-id nominates a class, the name
specified after the nested-name-specifier is looked up in the scope of the
class ([class.member.lookup]), except for the cases listed below. The name
shall represent one or more members of that class or of one of its base
classes ([class.derived]). [ Note: A class member can be referred to using a
qualified-id at any point in its potential scope ([basic.scope.class]). — end
note  ]
Yes, it merely specifies the class name/namespace the object was declared in. There can be more contrived cases, like this one:
struct Base {
virtual int answer() const { return 42; }
};
struct Left: public virtual Base {
virtual int answer() const { return 314; } // raise the heat
};
struct Right: public virtual Base {
virtual int answer() const { return -42; } // to the other side
};
struct Bottom: Left, Right {
virtual int answer() const { return Base::answer(); } // back to basics
};
#include <iostream>
int main() {
Bottom b;
std::cout << b.answer() << std::endl; // 42
std::cout << b.Right::answer() << std::endl; // -42
std::cout << b.Left::answer() << std::endl; // 314
std::cout << b.Base::answer() << std::endl; // again, 42
}
The thing with static members, you cannot access them other way (and they cannot be virtual, btw.) (Still, if class Child derives Base and both define a static member staticMember, you should use qualified forms — either Base::staticMember or Child::staticMember — to disambiguate between the two; unqualified version refers to Child's one in this case.)
But non-static methods have an object context inside them, so members can be used unqualified — still they can be used other way, too.
P.S. Where did that this-> originate from? I sometimes see it every here and there, still nobody has been able to explain why.
There are several reasons to qualify with class name an instance variable (or member function). This list is not exhaustive, and only mentions cases where we would use it on object instances, not types:
Inside a member function, if derived and parent have the same member name, the derived name hides the base. Qualification can allow access to the base. This applies to both variables and member functions.
If inside a member function in hierarchy with multiple inheritance, it can select between which parent you want to use.
It can be used to bypass the virtual function dispatch mechanism by calling the function implementation in the type specified, rather than in the most overriding type. Example: d.Base::foo();
It can be used to specify a member that was hidden by a local variable, similar to qualifying a member with this-> (Though I've never seen this done, and prefer this-> instead.)
It is frequently used in conjunction with a "using" declaration, to bring base class function names into the overload set of the derived class that adds some of its own with the same name. Without this, the base names would be hidden.

Initialize a private static field outside the class (the meaning of private in this case) and calling to static functions

If I will define a private static field in class. Given that it's a private field, can't I initialize it outside the class?
class X{
static int private_static_field;
public:
static void setPrivateStaticField(int val);
};
void X::setPrivateStaticField(int val) {
private_static_field = val;
}
int X::private_static_field(0); // something like that it's ok? if yes, I must write this line? why? can I write it in main?
It's look that it's ok (according to the compiler), but if so, I don't understand the concept of private - How it's ok if it's outside the class?
In addition, given the class above, and the next code:
int main() {
X x1();
x1.setPrivateStaticField(3);
return 0;
}
What is the meaning of x1.setPrivateStaticField(3); , after all, this function is static and hence it's not related to some object.
Hence, I don't understand how it's ok to call setPrivateStaticField with object (x1) ?
(I thought that just X::setPrivateStaticField(3); will be ok and that x1.setPrivateStaticField(3); will be error)
I don't understand the concept of private - How it's ok if it's outside the class?
There is no contradiction here. Prior to C++ 17 static member variables required a definition that is placed separately from the class declaration.
Despite the fact that the text of the definition is placed outside the class, the member variable remains part of the class where it is declared, and retains its accessibility according to its declaration inside the class. This includes private accessibility.
What is the meaning of x1.setPrivateStaticField(3); , after all, this function is static and hence it's not related to some object.
Although C++ compiler lets you call static member functions on the object, it is cleaner to call them using scope resolution operator :: and the class name:
X::setPrivateStaticField(3);
Allowing or disallowing class method calls on an instance is up to the designers of the language. C++ designers decided to allow it; designers of other programming languages disallow it, or require compilers to issue a warning.
Within a class definition static data members are declared but not defined. So they even can have an incomplete type.
So this record
int X::private_static_field(0);
is a definition of the static data member declared in the class definition like
class X{
static int private_static_field;
// ...
This record
x1.setPrivateStaticField(3);
means an access to a class member. Static members are also class members. Using this access method the compiler will know to search the name setPrivateStaticField in the class definition because the name x1 defines an object of the class X.
Another way to access a static member is to use the following record
X::setPrivateStaticField

Is a local class in a method of a class a friend of this class?

I have an outer class A. It has a method A::fun. In this method, it has a local or inner class B. My question is: Is B a friend of A?
I think it is not. Is it right? If so, I think let class B a friend of A is very beneficial since B can access to A's private and protected members. And moreover, sinceB is local in a methods, it is not accessible by others and thus safe as a friend of A. How to work around to let B access to A's private and protected members?
No they are not friends.
But local classes have the same access to the names outside the function as the function itself.
The standard says :
9.8 Local class declarations [class.local]
A class can be declared within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class shall not odr-use (3.2) a variable with automatic storage duration from an enclosing scope.
The big difference to take in count is that your local class will only be accessible inside the function.
But after that :
A friend of a class is a function or class that is given permission to use the private and protected member names from the class.
The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. That is, it can access to protected and private members of the class the function belongs.
No they are not friends. But does it matter?
Not really! consider these facts:
Within the member function you will always have access to the members of the class to which the function belongs.
You cannot access the local class anywhere beyond the function.
So it hardly matters if they are friends or not. You are always going to be referring the outer class members inside its member function.
Online Sample:
class A
{
int i;
void doSomething()
{
class B{public: int ii;};
B obj;
obj.ii = i;
}
};
int main()
{
return 0;
}
This compiles in Clang:
class A {
typedef int Int;
void fn();
};
void A::fn() {
class B {
Int i;
};
}
The inner class has access to A's private members, but not because it is a friend, but because it is considered a member. Since members of a class have access to private members, this includes inner classes as well as local classes of member functions.
See [class.access]p2.

Where would you use a friend function vs. a static member function?

We make a non-member function a friend of a class when we want it to access that class's private members. This gives it the same access rights as a static member function would have. Both alternatives would give you a function that is not associated with any instance of that class.
When must we use a friend function? When must we use a static function? If both are viable options to solve a problem, how do we weigh up their suitability? Is there one that should be preferred by default?
For example, when implementing a factory that creates instances of class foo which only has a private constructor, should that factory function be a static member of foo (you would call foo::create()) or should it be a friend function (you would call create_foo())?
Section 11.5 "The C++ Programming Language" by Bjarne Stroustrup states that ordinary member functions get 3 things:
access to internals of class
are in the scope of the class
must be invoked on an instance
friends get only 1.
static functions get 1 and 2.
The question seems to address the situation where the programmer needs to introduce a function that does not work on any instance of a class (hence the possibility of choosing a static member function). Therefore, I will limit this answer to the following design situation, where the choice is between a static function f() and a friend free function f():
struct A
{
static void f(); // Better this...
private:
friend void f(); // ...or this?
static int x;
};
int A::x = 0;
void A::f() // Defines static function
{
cout << x;
}
void f() // Defines friend free function
{
cout << A::x;
}
int main()
{
A::f(); // Invokes static function
f(); // Invokes friend free function
}
Without knowing anything in advance about the semantics of f() and A (I'll come back to this later), this limited scenario has an easy answer: the static function is preferable. I see two reasons for this.
GENERIC ALGORITHMS:
The main reason is that a template such as the following can be written:
template<typename T> void g() { T::f(); }
If we had two or more classes that have a static function f() on their interface, this would allow us writing one single function that invokes f() generically on any such class.
There is no way to write an equivalent generic function if we make f() a free, non-member function. Although it is true that we could put f() into a namespace, so that the N::f() syntax could be used to mimic the A::f() syntax, it would still be impossible to write a template function such as g<>() above, because namespace names are not valid template arguments.
REDUNDANT DECLARATIONS:
The second reason is that if we were to put the free function f() in a namespace, we would not be allowed to inline its definition directly in the class definition without introducing any other declaration for f():
struct A
{
static void f() { cout << x; } // OK
private:
friend void N::f() { cout << x; } // ERROR
static int x;
};
In order to fix the above, we would to preceed the definition of class A with the following declaration:
namespace N
{
void f(); // Declaration of f() inside namespace N
}
struct A
{
...
private:
friend void N::f() { cout << x; } // OK
...
};
This, however, defeats our intention of having f() declared and defined in just one place.
Moreover, if we wanted to declare and define f() separately while keeping f() in a namespace, we would still have to introduce a declaration for f() before the class definition for A: failing to do so would cause the compiler to complain about the fact that f() had to be declared inside namespace N before the name N::f could be used legally.
Thus, we would now have f() mentioned in three separate places rather than just two (declaration and definition):
The declaration inside namespace N before A's definition;
The friend declaration inside A's definition;
The definition of f() inside namespace N.
The reason why the declaration and definition of f() inside N cannot be joined (in general) is that f() is supposed to access the internals of A and, therefore, A's definition must be seen when f() is defined. Yet, as previously said, f()'s declaration inside N must be seen before the corresponding friend declaration inside of A is made. This effectively forces us to split the declaration and the definition of f().
SEMANTIC CONSIDERATIONS:
While the above two points are universally valid, there are reasons why one might prefer declaring f() as static over making it a friend of A or vice versa which are driven by the universe of discourse.
To clarify, it is important to stress the fact that a member function of a class, whether it is static or non-static, is logically part of that class. It contributes to its definition and thus provides a conceptual characterization of it.
On the other hand, a friend function, in spite of being granted access to the internal members of the class it is friend of, is still an algorithm which is logically external to the definition of the class.
A function can be friend of more than one class, but it can be member of just one.
Thus, in a particular application domain, the designer may want to keep into consideration the semantics of both the function and the class when deciding whether to make the former a friend or a member of the latter (this applies not only to static functions, but to non-static functions as well, where other language constraints may intervene).
Does the function logically contribute to characterize a class and/or its behavior, or is it rather an external algorithm? This question can't be answered without knowledge of the particular application domain.
TASTE:
I believe that any argument other the ones just given stems purely from a matter of taste: both the free friend and the static member approach, in fact, allow to clearly state what the interface of a class is into one single spot (the class's definition), so design-wise they are equivalent (modulo the above observations, of course).
The remaining differences are stylistic: whether we want to write the static keyword or the friend keyword when declaring a function, and whether we want to write the A:: class scope qualifier when defining the class rather than the N:: namespace scope qualifier. Thus, I will not comment further on this.
The difference is clearly expressing the intent of the relationship between the class and the function.
You use friend when you want to intentionally indicate a strong coupling and special relationship between two unrelated classes or between a class and a function.
You use static member function when the function is logically a part of the class to which it is a member.
Friend functions (and classes) can access the private and protected members of your class.
There's rarely a good case for using a friend function or class. Avoid them in general.
Static functions may only access static data (that is, class-scoped data). They may be called without creating an instance of your class. Static functions are great for circumstances you want all of the instances of your class to behave the same way. You can use them:
as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without instantiating the class.
Friend functions are functions which are not in the class and you want to give them access to private members of your class.
And this(static vs. friend) is not a matter of using one vs the other since they are not opposites.
The standard requires that operator = () [] and -> must be members, and class-specific
operators new, new[], delete and delete[] must be static members. If the situation
arises where we don't need the object of the class to invoke a function, then make
the function static. For all other functions:
if a function requires the operators = () [] and -> for stream I/O,
or if it needs type conversions on its leftmost argument,
or if it can be implemented using the class' public interface alone,
make it nonmember ( and friend if needed in the first two cases)
if it needs to behave virtually,
add a virtual member function to provide the virtual behaviour
and implement in terms of that
else
make it a member.
Static function can only access members of one class. Friend function has access to several classes, as explained by the following code:
class B;
class A { int a; friend void f(A &a, B &b); };
class B { int b; friend void f(A &a, B &b); };
void f(A &a, B &b) { std::cout << a.a << b.b; }
f() can access data of both A and B class.
One reason to prefer a friend over static member is when the function needs to be written in assembly (or some other language).
For instance, we can always have an extern "C" friend function declared in our .cpp file
class Thread;
extern "C" int ContextSwitch(Thread & a, Thread & b);
class Thread
{
public:
friend int ContextSwitch(Thread & a, Thread & b);
static int StContextSwitch(Thread & a, Thread & b);
};
And later defined in assembly:
.global ContextSwitch
ContextSwitch: // ...
retq
Technically speaking, we could use a static member function to do this, but defining it in assembly won't be easy due to name mangling (http://en.wikipedia.org/wiki/Name_mangling)
Another situation is when you need to overload operators. Overloading operators can be done only through friends or non-static members. If the first argument of the operator is not an instance of the same class, then non-static member would also not work; friend would be the only option:
class Matrix
{
friend Matrix operator * (double scaleFactor, Matrix & m);
// We can't use static member or non-static member to do this
};
A static function is a function that does not have access to this.
A friend function is a function that can access private members of the class.
You would use a static function if the function has no need to read or modify the state of a specific instance of the class (meaning you don't need to modify the object in memory), or if you need to use a function pointer to a member function of a class. In this second instance, if you need to modify the state of the resident object, you would need to pass this in and use the local copy. In the first instance, such a situation may happen where the logic to perform a certain task is not reliant on an object's state, yet your logical grouping and encapsulation would have it be a member of a specific class.
You use a friend function or class when you have created code that is not a member of your class and should not be a member of your class, yet has a legitimate purpose for circumventing the private/protected encapsulation mechanisms. One purpose of this may be that you have two classes that have need of some common data yet to code the logic twice would be bad. Really, I have only used this functionality in maybe 1% of the classes I've ever coded. It is rarely needed.
A friend function can not be inherited while a static function can be. So when an aim can be achieved with both static function and friend function, think that whether you want to inherit it or not.
Static function can be used in many different ways.
For example as simple factory function:
class Abstract {
private:
// no explicit construction allowed
Abstract();
~Abstract();
public:
static Abstract* Construct() { return new Abstract; }
static void Destroy(Abstract* a) { delete a; }
};
...
A* a_instance = A::Conctruct();
...
A::Destroy(a_instance);
This is very simplified example but I hope it explains what I meant.
Or as thread function working with Your class:
class A {
public:
static void worker(void* p) {
A* a = dynamic_cast<A*>(p);
do something wit a;
}
}
A a_instance;
pthread_start(&thread_id, &A::worker, &a_instance);
....
Friend is completely different story and they usage is exactly as described by thebretness
Friend functions can access the private and protected members of other classes.
Means they can be used to access all the data weather it is private or public.
So friend functions are used to access that data which static methods can not.
Those methods are made static which are called so many times that declaring a different location inside every object, for them becomes too costly(In terms of memory).
This can be made clear with the help of example:
Let the class's name is fact and its data member is n(which represents integer whose factorial is concern)
then in this case declaring find_factorial() as static would be wise decision!!
They are used as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Now we are clear with following questions..
When a friend function is used? When a static function is used?
Now If both are viable options to solve a problem,
We can weight up their suitability in terms of accessibility(accessibility of Private data) and memory efficiency.
By default no one can be preferred as there are many situation when we need better memory management and sometimes we are are concerned with the scope of data.
For example:
foo::create() will be preferred over create_foo() when we have to call create() method after every small instance of time and we are not interested on scope of data(Private data)
And if we are interested to get the private information of more than one class(s) then create_foo() will be preferred over foo::create().
I hope this would help you!!
Here is what I think it is:
Friend function- when you need access to a different class member, but the classes are not related. Static function- when you no not need access to the 'this' pointer. But, I have a feeling there is more to it....
Static data members always share the memory.
only static function can used static data members.
static member function can be called with class name.
They must be defined outside of the class when we create a object of static member or member function in the class. It will automatically initialize the value.
It always used keyword static.
Static members can share by all the objects.
Type and scope of data members and member function is outside of the class.
A static member variable must be defined outside of the class.