Can some one please explain the scope of int A and int B in the void func() and in void func1()?
class C {
struct S {
int A;
};
int B
public :
void func(){
}
void func1(){
}
};
Not sure I fully understand what you're asking for, but if I do, I'll try to answer.
Functions func() and func1() are member functions of C, so they have identical access to the exact same names here. Variable B, being a member variable of C, can be referred directly withing func() and func1() without qualifying it with any namespace.
Variable A on the other hand, being a public, non-static member variable of S, requires first instantiating an object of type S before being accessed, like this:
void func()
{
S s;
B = 0; // Directly accessible, member variable of `C`
s.A = B; // A is a non-static member variable of `S`, requires an object
A == 3; // ERROR! A is not a member variable of C
}
Related
I was trying this way:
(*point).member1.member2
But it doesn't work.
How do I make a reference of a member of a struct that is inside of another struct?
A bit unclear what you are asking for, but probably this is what you are trying to do:
struct A {
struct B {
void f() {}
};
};
int main() {
// pointer to member function of B
// to which A::B::f is assigned
void (A::B::*member)() = &A::B::f;
A::B b{};
// invoke member on b, equivalent to b.f()
(b.*member)();
}
member is a pointer to a member of a class that is defined within another class, as mentioned in your title.
The last line of main just invokes the member for b. It's equivalent to b.f();.
C++ compilers warn when a local variable shadows another variable.
e.g. https://godbolt.org/g/TYYf8F
However none of the major C++ compilers warn when a member of a derived class shadows a member of the base class:
class A
{
int _memberVar = 2;
public:
virtual int memberVar()
{
return _memberVar;
}
};
class B : public A
{
int _memberVar = 3;
};
int main()
{
A* pB = new B();
return pB->memberVar(); // returns 2
}
see https://godbolt.org/g/fBMUAd
Is there a reason behind it?
Virtual is a mechanism in the caller of a function to decide which function to call. It does not make the function to somehow behave "virtual". Since you did not overwrite the function B::memberVar() it is still calling A::memberVar(), and this behaves as any other member function of A.
Can a class written in a method of another class(inner class), access the methods variables? I mean in the code below:
class A
{
void methodA( int a )
{
class B
{
void processA()
{
a++;
}
};
std::cout<<"Does this program compile?";
std::cout<<"Does the value of the variable 'a' increments?";
};
};
Is this legal?Does, the value of 'a' increments? Please suggest how.
Thanks,
Pavan.
No it is not legal
class B is a Local class to methodA().
class B cannot access nonstatic "automatic" local variables of the enclosing function. But it can access the static variables from the enclosing scope.
There are several restrictions on what local classes can have access to.
Here is an reference from the C++ Standard:
9.8 Local class declarations [class.local]
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.
Short answer, no. Local classes in C++ do not have access to their enclosing function variables (with a few caveats). You can read more about C++ local classes here, and also see this nice SO answer. For emphasis:
A local class is declared within a function definition. Declarations in a local class can only use type names, enumerations, static variables from the enclosing scope, as well as external variables and functions.
int x; // global variable
void f() // function definition
{
static int y; // static variable y can be used by
// local class
int x; // auto variable x cannot be used by
// local class
extern int g(); // extern function g can be used by
// local class
class local // local class
{
int g() { return x; } // error, local variable x
// cannot be used by g
int h() { return y; } // valid,static variable y
int k() { return ::x; } // valid, global x
int l() { return g(); } // valid, extern function g
};
}
int main()
{
local* z; // error: the class local is not visible
// ...}
We're not allowed to define a functor struct inside a function because one is not allowed to use function declared structs in the instantiation of function templates.
Are there any other significant pitfalls to be aware of? E.g. would this be bad:
int foo()
{
struct Scratch
{
int a, b, c;
};
std::vector<Scratch> workingBuffer;
//Blah Blah
}
1. C++ standard forbids using locally-defined classes with templates.
14.3.1/2: A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.
A code example:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as
// template-argument
X<S*> x4; // error: pointer to local type
// used as template-argument
}
Here is a little more reference from IBM documentation:
2. Declarations in a local class can only use type names, enumerations, static variables from the enclosing scope, as well as external variables and functions.
A Code Example:
int x; // global variable
void f() // function definition
{
static int y; // static variable y can be used by
// local class
int x; // auto variable x cannot be used by
// local class
extern int g(); // extern function g can be used by
// local class
class local // local class
{
int g() { return x; } // error, local variable x
// cannot be used by g
int h() { return y; } // valid,static variable y
int k() { return ::x; } // valid, global x
int l() { return g(); } // valid, extern function g
};
}
int main()
{
local* z; // error: the class local is not visible
return 0;
}
3. A local class cannot have static data members
A Code Example:
void f()
{
class local
{
int f(); // error, local class has noninline
// member function
int g() {return 0;} // valid, inline member function
static int a; // error, static is not allowed for
// local class
int b; // valid, nonstatic variable
};
}
The scope of the local classes is the function in which they're defined.But that isn't interesting in itself1.
What makes local classes interesting is that if they implement some interface, then you can create instances of it (using new) and return them, 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. They cannot be used as template argument, however.
If they defined inside 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.
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.
Local structs / classes can't have static data members, only static member functions. Also, they can't be templates.
Yes. Local classes can't be used as template parameters in C++03
local structs are perfectly legal, even in C++98. You cannot use them with templates in C++98 though, whereas you can in C++0x. g++ 4.5 supports using local structs with templates in -std=c++0x mode.
Can you explain why this is not allowed,
#include <stdio.h>
class B {
private:
int a;
public:
int a;
};
int main() {
return 0;
}
while this is?
#include <stdio.h>
class A {
public:
int a;
};
class B : public A{
private:
int a;
};
int main() {
return 0;
}
In both the cases, we have one public and one private variable named a in class B.
edited now!
In both the cases, we have one public
and one private variable named a in
class B.
No, thats not true.
In the first case, you can't have two identifiers with the same name in the same scope. While in the second case, B::a hides A::a, and to access A::a you have to fully qualify the name:
b.a = 10; // Error. You can't access a private member.
b.A::a = 10; // OK.
Because B::a hides A::a in the second example. You can still access it, but it needs explicit qualification for the compiler to figure out you are asking for the member of parent class with the same hame.
In the first example both a's are in the same scope, while in the second example the scopes are different.
Class B in the first example is not valid because C++ cannot distinguish members by their access specifiers (public/private/protected). However, namespaces are a way for C++ to distinguish members. In class B in the second code you don't have a "public a" and a "private a", you have B::a and A::a.
Even if declaring members of the same name/signature with different access specifiers was allowed, there would be no way to address the correct member.
The first isn't allowed because it leads to ambiguous definitions. In the 2nd, although you do have both a public and a private a integer variable, you've hidden A::a inside your B class. The compiler knows implicitly what you want because there is a way to explicitly access a hidden variables.
I also believe that it boils down to name mangaling: storage specifiers don't end up as part of the actual name. I could be wrong on this however.
The easiest way to illustrate why one is allowed and why the other isn't is to look at how the compiler would compile a member function that uses each variable.
Inside your class b:
class b {
int a;
public:
int a;
void myMethod()
{
a = 10; //what a should the compiler use? Ambiguous, so the compiler sez BZZT.
}
}
For the 2nd example:
class A
{
public:
int a;
}
class B: public A
{
private:
int a;
void someMethod()
{
a = 10; //implied that you are using B::a (which may be a programmer error)
}
}