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.
Related
Im currently learning OOP in C++.
class Base {
public:
Base() {}
protected:
SomeClass variable;
};
class Child : public Base {
public:
Child() {}
void method() {
// Access variable
}
};
When accessing a member variable in the base class from a derived class, what is the difference between these two notations?
this->variable
Base::variable
And what is preferred when?
The "full" expression naming that variable is:
this->Base::variable
It says:
The name is variable
It lives in the type Base
The object owning this instance is this
Since you're inside a scope where base members will be found automatically, you don't need Base::.
And, since you're inside a member function where all members will be found automatically, you don't need this->.
You might need Base:: to disambiguate from some other variable in scope, but the this-> part likely takes care of that for you already.
So, usually, you only need any of the following:
variable (normally)
this->variable (if something from another scope is hiding it)
Base::variable (if something in the current type is hiding it)
As for what's "preferred"… as long as you've satisfied your needs, you can do whatever you like. But simpler is usually deemed "better", and will invite fewer questions from others reading your code.
There is a third option missing: Just variable.
And what is preferred when?
The one that is most pleasing to your aesthetics.
There are some cases in which some of the options won't work. In such cases, it is preferable to use those that do work. Examples are: Plain variable name cannot be used if it has been shadowed by another variable. Qualified name cannot be used in some cases where the base depends on a template variable.
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.
I'm trying to understand the following piece of code:
lock_server::lock_server(class rsm *_rsm)
{
//code
}
I know that this is the constructor for the class, but I don't understand its argument.
I'm guessing that this is a pointer (with name _rsm) that points to a class? Does that make sense? Where can I find documentation about this?
class or struct keywords are optional in C++ when specifying a type, and usually omitted.
That is, the following functions have an equivalent signature:
class mytype { ... };
void f(mytype* data); // compiler "understands" that mytype is a class
void g(class mytype* data);
If the class in question wasn't declared beforehand, you have to include the word class.
The keyword class before the term rsm is not necessary in C++ (unlike in C where you must specify the word struct).
However that doesn't mean it is forbidden and whoever wrote that felt it was good style, albeit it's intuitive that rsm is a type of some sort (not necessarily a class, could be a typedef to a class)
The purpose of that constructor is to construct an object of type lock_server with a pointer to a modifiable rsm object. My guess is that rsm has some kind of lock method which will be called from the constructor, and an unlock method which will be called from the destructor.
The purpose of the lock_server class is to implement what is called RAII: a stupid acronym but in real life it means automated resource management - when the object leaves scope the destructor kicks in which releases the resource it is holding, in this case a lock to the rsm object.
It is a pointer, to an object of class rsm.
The keyword class is optional, as long as the class rsm was previously defined/declared.
However, if the class wasn't previously declared at the point in the source, the class keyword is necessary. In this case the rsm declared as an incomplete class type.
I have a simple code below:
class B;
class A{
B b;
};
class B{
public:
B(){
}
};
In class A's definition, I have a B-typed property. Using MS Visual Studio to compile, I've got the following error:
error C2079: 'A::b' uses undefined class 'B'
Due to some reasons, I can't put class B's definition before class A's one. Any idea?
The compiler is already telling you what's wrong : A has a member data b which is of an undefined type. Your forward declaration:
class B;
is just that : a declaration, not a definition. Since class A contains an instance of B directly (not just a pointer to B), the compiler needs to know the exact size of B : it needs its definition, not just a declaration, i.e. a promise that B will exist at some point.
The simplest thing to do here would be to reorder things this way:
class B{
public:
B(){
}
};
class A{
B b;
};
Edit : see also this question for the difference between declaration and definition.
Further edit : an alternative would be to change your member data to a pointer or a reference.
Do note that this isn't a trivial syntax change: it has implications on the life-cycle of your objects since the object pointed by A::b may then survive the destruction of A.
If what you want is composition (B is a part of A and dies with A), using a pointer will make your life harder with little benefits.
More edits(!) : just realized I misread the end of your question; what are the reasons preventing you from declaring B before A ?
If they cannot be worked around, you may have to go the pointer route. These reasons might be a sign that your objects are too tightly coupled though ! (perhaps B needs to be an inner class of A ? Or simply be merged into a single object ?)
class A;
class B {
A * getA();
};
class A {
B b;
};
This is the typical way to solve this. You must have B's definition in order to have a B b; member.
You need a forward declaration in order to declare a reference/pointer to B, you need the full definition in order to do anything else with B (such as defining a variable, calling a member function and so on)
You can do what you wish if you change the reference to b into a pointer to B.
class A{
B* bPtr;
};
class B{
public:
B(){
}
};
In principle, you don't need an explicit declaration - that is, a forward declaration is all that is needed - when you don't need the actual size of the class, or access to the types and member functions inside the class.
In your original example, you are making a direct reference to B. As a result, the compiler needs to know everything about B, thus requiring an explicit declaration instead of a forward one.
By having your A class declaration using a pointer to B, then you can get away with a forward declaration.
edit
Some links might explain the concept for you:
http://www.goingware.com/tips/parameters/notrequired.html
http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml
http://www.codeguru.com/forum/showthread.php?t=358333 (see post #2)
http://en.wikipedia.org/wiki/Forward_declaration
C++ has the concept of an "incomplete" class and it is something you need to know.
Using an incomplete class allows you, in many situations, to use a class just knowing it is one, without knowing what is in it.
This enables the class detail to change later without requiring a recompile, thus it is a far weaker dependency in the coupling model.
You need a complete class to:
Have an instance of one.
Derive from it
Call any method on it.
delete a pointer to it.
You only need an incomplete class to:
Hold a pointer or reference to it.
Pass a pointer or reference to a function that takes a pointer or reference. (This can be a function that deletes the pointer, as long as it is fully defined at that point).
I think you only need an incomplete class to declare a function that returns one, and possibly to declare a function that takes one as a parameter, but at the time you define or call the function it needs to be complete, even if you don't use the return value.
Typically the 'using' declaration is used to bring into scope some member functions of base classes that would otherwise be hidden. From that point of view it is only a mechanism for making accessible information more convenient to use.
However: the 'using' declaration can also be used to change access constraints (not only for functions but also for attributes). For example:
class C{
public:
int a;
void g(){ cout << "C:g()\n"; }
C() : a(0){}
};
class D : public C{
private:
using C::a;
using C::g;
public:
D() { a = 1; }
};
int main(void){
D d;
cout << d.a << endl; //error: a is inaccessible
C *cp = &d;
cout << cp->a << endl; //works
d.g(); //error: g is inaccessible
cp->g(); //works
return 0;
}
I think this limitation of access in the derived class is actually of no use, because you can always access g() and a from a pointer to the base class. So should't there be at least some kind of compiler warning? Or wouldn't it been even better to forbid such limitation of access by a derived class? The using declaration is not the only possibility to add constraints to access. It could also be done via overriding a base class' function an placing it in a section with more access constraints.
Are there some reasonable examples where it is indeed nessecary to limit access in such a way? If not I don't see why it should be allowed.
And another thing: at least with g++ the same code compiles well without the word 'using'. That means for the example above: it's possible to write C::a; and C::g; instead of using C::a; using C::g; Is the first only a shortcut for the latter or are there some subtle differences?
//EDIT:
so from the discussion and answers below my conclusion would be:
- it's allowed to limit access constraints in derived classes with public inheritance
- there are useful examples where it could be used
- it's use might cause problem in combination with templates (e.g. a derived class could not be a valid parameter for some template class/function any more although it's base is)
- a cleaner language design should not allow such use
- compiler could at least issue some kind of warning
With regard to your declaration without using: These are called "access declarations", and are deprecated. Here is the text from the Standard, from 11.3/1:
The access of a member of a base class can be changed in the derived class by mentioning its qualified-id in
the derived class declaration. Such mention is called an access declaration. The effect of an access declaration qualified-id; is defined to be equivalent to the declaration usingqualified-id; [Footnote: Access declarations are deprecated; member using-declarations (7.3.3) provide a better means of doing the same things. In earlier versions of the C++ language, access declarations were more limited; they were generalized and made equivalent to using-declarations - end footnote]
I would say that most often it's not good to change public members to private or protected members in the derived class, because this will violate the substitution principle: You know a base class has some functions, and if you cast to a derived class then you expect those functions to be callable too, because the derived class is-a base. And like you already mentioned, this invariant is already enforced anyway by the language allowing to convert (which working implicitly!) to a base class reference, or qualifying the function name, and then calling the (then public) function.
If you want to forbid someone calling a set of functions of the base, then i think this hints that containment (or in rare cases, private inheritance) is a better idea.
While the using declaration you showed does provide a mechanism to change access level (but only down), that is not the primary use of it in such a context. A using context there is primarily intended to allow access to functions that would otherwise be shadowed from the base class due to the language mechanics. E.g.
class A {
public:
void A();
void B();
};
class B {
public:
using A::B;
void B(int); //This would shadow A::B if not for a using declaration
};
The declaration
using C::a
brings "a" to the local naming scope so that you can later use "a" to refere to "C::a"; since that, "C::a" and "a" are interchangeable as long as you don't declare a local variable with name "a".
The declaration does not change access rights; you can access "a" in the subclass only because "a" is not private.