I'm regular to write in java,
and I'm a little bit confused about static nested class in C++.
I'm trying to declare a static class, but I get an error :
class D
{
public:
static class Listener
{
public :
void foo()
{
cout << "foo" <<endl;
}
};
};
And I getting following error
"storage class can only be specified for objects and functions"
(I'm using an online compiler).
The correct terminology would be "static nested class".
Static nested classes in Java are like normal nested classes in C++, so just drop the static and it should work fine.
Non-static ones like in Java would be a bit harder to emulate in C++, because there is no compiler magic to automatically provide the context of the outer class. You would have to work around the issue by storing a reference to the outer class in the inner class, initialising it in the constructor of the inner class, and accessing members of the outer class explicitly via the reference.
Classes in C++ are merely nested type definitions, so only act as namespaces for nested type definitions.
If you declared a class type definition as static anywhere (nested or not nested), you'd get a compiler warning and it will be stripped off. Classes cannot have storage class specifiers and static has been repurposed something different inside a class. This is because class types don't have storage at all and are just templates (so linkage doesn't make sense; they don't even survive that far), and method definitions are compiler directives that the compiler is able to concretise when it chooses, but just so easily can exclude from the assembly output, unlike regular functions, which are guaranteed to be present when placed in another translation unit, so all class members are effectively inline (unless static, then they need to be explicitly made inline to provide an inline definition). static used on a class inside a class is redundant because classes nested are implicitly static in this sense.
When you instantiate the parent class, it does not include the nested class because this is just a compiler directive. You have to include an object of the class as one of the members, where the class type definition is in scope:
class c {
public :
int i;
class s f; //not allowed
class s;
class s k; //not allowed, still has forward declaration type
class s {
public:
int j;
};
s p; // allowed
};
You can forward declare a nested class in a class but a member cannot be defined with a forward declaration incomplete type unless it is a pointer or reference to it, but it can be with an incomplete type if the type has been completed above it in the scope.
Unlike a namespace however, you cannot access non-static members of the parent class from the nested class (this type of static and non-static do not exist in namespaces anyway). This is because the nested class is instantiated separately to the parent class and the parent class may never be instantiated. It just so happens that the programmer may initialise the nested object in the parent object, just as it could store it in a pointer in the object or a local pointer and initialise it on the heap, but at the object level, they are separate objects and where their type definitions are is irrelevant. If you called a non-static member of the parent class, the compiler would have to pass an object of the parent class to it. It could theoretically use the parent class type definition to determine the offset it will be at in memory for the member it fills, but it might not always be a subobject of a parent object. In order for this functionality to be allowed, the compiler would have to throw an error if the subclass is instantiated without the parent class being instantiated and it being assigned as a subobject of the parent subobject.
Related
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
I've been trying to understand a piece of code that goes like this:
class A {
// some class definition
}
class B {
public:
virtual A *someMethod();
virtual class A *someOtherMethod();
}
I can't seem to understand the difference (or if any exists, for that matter) between someMethod and someOtherMethod - both appear to be virtual methods and both are overridden in classes that inherit from B.
Could someone shed some light on this virtual class syntax?
A is the class name, and class A is the elaborated type specifier.
If there's nothing else called A, then both refer to the class called A.
If there were something else (a function or variable, perhaps) called A, then an unqualified use of A would refer to that. You'd need the elaborated specifier class A to refer to the class. As mentioned in the comments, you can also use class A without a previous declaration of the class; the use of the elaborated specifier is enough to introduce the class name into the innermost namespace.
It has little to do with virtual function syntax; both forms can be used to specify the type, whether as the return type of a function or in any other context.
In C you used to have to write struct S to refer to a structure. In fact there was this pattern to deal with it: typedef S struct {}, which creates an unnamed structure, then gives it the name S through type aliasing.
C++ retained this ability, but aliases raw types automatically. In your case, A is a type alias to the formal name class A. Of course the automatic alias won't work if you have more than one A, but that's also a pretty big code smell.
TL;DR: both functions return the same thing. It's a remnant of C for backwards compatibility and extremely frowned upon when used.
In python we may use self keyword to declare class variables within a member function of the class which can be subsequently used by other member functions of the class.
How to do such a thing in C++.
Python Code:
class abc():
{
def __init__(self):
self.help='Mike' #self.help is the class variable and can be used in other methods
def helpf():
morehelp=self.help+' Bike'
}
C++ code:
class abc
{
public:
abc();
public:
void helpf(void);
};
abc::abc()
{
string help="Mike";
}
void abc::helpf()
{
string morehelp=this->helpf+" Bike";// this keyword sounded like the one but...
}
There is no way to do such thing in C++.
You should declare members in class, not in functions.
You cannot declare class members inside functions in C++. You have to declare them outside functions, like in JAVA
class abc
{
public:
int publicInt; // This is a public class variable, and can be accesed from outside the class
int abc();
private:
float privateFloat; // This is private class variable, and can be accesed only from inside the class and from friend functions
void helpf(void);
};
that is not possible. Declaring variables inside a member function are local to that member function. If you want to use variables in your member function you have to declare class variables.
This works in Python because Python allows you to add a attribute to an object from anywhere simply by assigning to it. It attaches to that object, rather than the object's class. In keeping with Python's dynamic language philosophy, and particularly with its lack of variable declarations, all of this - including the decision about which attributes do or don't exist - happens at run time.
C++'s explicitly does not have a concept of one particular object having an attribute - all member variables are associated with the class, even if they take independent values on each instance. The set of all possible member variables, and which types they hold, is shared class-wide and set in stone at compile time. Because of this, what you're asking for basically doesn't make sense in C++.
class base {
public:
base a;
};
It gives compilation error.
class base {
public:
static base a;
};
whereas this code does not give compilation error
Because static class members are not stored in the class instance, that's why a static would work.
Storing an object inside another object of the same type would break the runtime - infinite size, right?
What would sizeof return? The size of the object needs to be known by the compiler, but since it contains an object of the same type, it doesn't make sense.
I'm guessing the error is something like
field ‘a’ has incomplete type
This is because when not static, the class A is not fully defined until the closing brace. Static member variables, on the other hand, need a separate definition step after the class is fully defined, which is why they work.
Search for the difference between declaration and definition for more thorough explanations.
#include<iostream>
using namespace std;
class base
{
public:
virtual void add() {
cout << "hi";
}
};
class derived : public base
{
private:
void add() {
cout << "bye";
}
};
int main()
{
base *ptr;
ptr = new derived;
ptr->add();
return 0;
}
Output is bye
I dont have a problem with how this is implemented. I understand you use vtables and the vtable of derived contains the address of the new add() function. But add() is private shouldn't compiler generate an error when I try to access it outside the class? Somehow it doesn't seem right.
add() is only private in derived, but the static type you have is base* - thus the access restrictions of base apply.
In general you can't even know at compile time what the dynamic type of a pointer to base will be, it could e.g. change based on user input.
This is per C++03 §11.6:
The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
[...] Access is checked at the call point using the type of the expression used to denote the object for which the member function is called [...]. The access of the member function in the class in which it was defined [...] is in general not known.
Access modifiers, such as public, private and protected are only enforced during compilation. When you call the function through a pointer to the base class, the compiler doesn't know that the pointer points to an instance of the derived class. According to the rules the compiler can infer from this expression, this call is valid.
It is usually a semantic error to reduce the visibility of a member in a derived class. Modern programming languages such as Java and C# refuse to compile such code, because a member that is visible in the base class is always accessible in the derived class through a base pointer.
To add a little to Georg's answer:
Remember that the compiler has no control over and cannot guarantee anything about derived classes. For example, I could ship my type in a library and derive from it in an entirely new program. How is the library compiler supposed to know that derived might have a different access specifier? The derived type didn't exist when the library was compiled.
In order to support this, the compiler would have to know access specifiers at runtime and throw an exception if you attempted to access a private member.