I've read about class with no name...
Got that
class
{
int i;
};
is not valied while
class
{
int i;
}A;
is valid.
But how to have a: 1) constructor and :2) destructor and: 3) how to pass as an argument???
If the class is unnamed then it can't have a custom constructor/destructor (although the compiler will generate the usual default ones for you). That means you can't pass an argument to it at construction. However, there's probably nothing stopping you from either (1) adding one or methods to the class to pass data to it after construction, or (2) giving the class a name in the first place.
The second thing is valid, but you cannot access the member i since it will be private. It is valid only because You have created an object A of that class type.
To have a constructor, I think you have to give the class a name. Use this:
class myclass
{
int i;
public:
myclass(int a) //This is the constructor
{
i = a;
}
~myclass() //This is the destructor
{
//Whatever you want to do on destroying the object
}
};
and instantiate that class as follows:
myclass A(10);
or similarly.
Note: This is just my interpretation, it can be done in many other ways.
You are doomed using the class locally and accessing it through the local object A, only.
You can use it in a template, though:
template <typename T>
inline void print(const T& a) {
std::cout << a.x << std::endl;
}
int main()
{
class {
public: int x;
} a;
a.x = 1;
print(a);
}
Related
My question is about this operator in C++, should we use it as much as possible? I given the following example to show my point:
class Abc
{
public:
int a_;
void fun();
};
void Abc::fun()
{
// option 1
a_ = 3;
// option 2
this->a_ = 3;
}
In the function class member fun(), we can invoke member variables in two ways, one is using this-> and the other is not using it. So my question is: which practice is encouraged? Thanks.
Under ordinary circumstances, you're right that you can use both. In such case, it's just a matter of style and the correct thing to do is follow the style guide of your project. Consistency is more important than personal preference in this regard.
However, there are two situations where using this-> can make a difference. One is when the member function has a parameter with the same name as a member; in such case, the name of the parameter hides the name of the member and you have to use this-> to refer to the member (first pointed out by #Krypton's answer):
void Abc::fun(int a_)
{
a_ = 3; // assigns into the parameter
this->a_ = 3; // assigns into the data member
}
The other situation is when you're working inside a class template and the member is inherited from a base class which depends on template parameters of your class template. In such case, unqualified lookup does not search dependent contexts and so the member would not be found. Using this-> turns the access into a dependent expression, which will be looked up at instantiation time, and thus resolved to the member correctly. Example:
template <class T>
struct Base
{
protected:
T a_;
};
template <class T>
struct Abc : Base<T>
{
void fun() {
a_ = 3; // error, not `a_` in scope
this->a_ = 3; // OK, found at instantiation time
}
};
In this situation, an alternative solution exists: make the name visible explicitly:
template <class T>
struct Abc : Base<T>
{
protected:
using Base<T>::a_;
public:
void fun() {
a_ = 3; // OK, found thanks to `using` declaration
}
};
If the variable and the parameter are named the same, using this is a must.
class Foo
{
public:
int _a;
void func(int _a) {
this->_a = _a;
}
};
this is also required when referring to a member of a base class that depends on a template parameter of the current class.
Otherwise, it is not necessary to use this.
I think it is more a matter of style. The use of additional this-> does not change the produced code.
Though you cannot use operator this-> in the initialization of class members before the constructor body, like
class Abc {
public:
Abc(int i): /*this-> is incorrect*/i(i) {}
private:
int i;
};
I prefer to use this-> to have a clear difference with other no-class members.
Then the code like the following is more readable
void foo(int i) { }
class Abc {
public:
Abc(int j) { this->foo(j); }
private:
void foo (int i) { this->i = i; }
int i;
};
Some people name class data members starting with m_, like m_i, m_j.
Some modern IDEs support semantic syntax highlighting that also helps to distinguish between local variables, class data members, global variables, functions.
I wonder why people say:
"Inheriting class doesn't inherit the constructor".
If you could CAN use the parent class' constructor, and the parameterless constructor are called automatically no matter what.
Example:
#include <iostream>
using namespace std;
class A {
private :
int x;
public :
A () {
cout << "I anyway use parameter-less constructors, they are called always" << endl;
}
A (const int& x) {
this->x = x;
cout << "I can use the parent constructor" << endl;
}
};
class B : public A {
private :
int y;
public :
B() {
}
B (const int& x, const int& y) : A (x) {
this->y = y;
}
};
int main() {
B* b = new B(1,2);
B* b1 = new B();
return 0;
}
http://ideone.com/e.js/6jzkiP
So is it correct to 'say', constructors are inherited in c++ ? What is exact definition of "inherit" in programming languages ?
Thanks in advance.
I wonder why people say: "Inheriting class doesn't inherit the constructor".
Perhaps it is best to illustrate this with an example:
struct Foo
{
Foo(int, int) {}
};
struct Bar : Foo
{
};
What it means is that there is no Bar::Bar(int, int) constructor that you can call, despite the existence of a constructor with the same parameter list in the base class. So you cannot do this:
Bar b(42, 42);
In C++11, you can actually inherit constructors, but you must be explicit about it:
struct Bar : Foo
{
using Foo::Foo;
};
Now, you can say Bar b(42, 42);
What they mean is that constructor signatures are not inherited.
In your example, B does not have a constructor taking a single const int& even though its base class does. In this sense it has not "inherited" the constructor (but can still make use of it).
I think what they mean is:
struct A {
A(int, int) { }
};
struct B : public A {
};
int main()
{
A a(1, 2); // ok
B b(1, 2); // error
}
To compare with “non-special” member functions:
struct A {
void f() { }
};
struct B : public A {
};
int main()
{
A a;
B b;
a.f(); // ok
b.f(); // ok too
}
But of course, from within B you can call accessible A constructors (as automatically generated ones do). Ditto for the destructor.
Note that in C++11 you can use the “inheriting constructors” feature:
struct A {
A(int, int) { }
};
struct B : public A {
using A::A;
};
int main()
{
A a(1, 2); // ok
B b(1, 2); // ok now
}
A derived class can/must see base class constructors in order to invoke them, for consistency. However, their signature is not exposed in the derived class, hence, one cannot construct the class without an explicitly defined constructor, which forwards the required arguments to the base class constructor.
In C++11, one can inherit constructors: What is constructor inheritance?
Another approach to circumvent 'proxy constructors' in C++ < 11: How to define different types for the same class in C++
In your example, the default ("parameterless" as you say) constructor of B does invoke the default constructor of A, but this does not mean that B "inherited" that constructor, only that it "has access to" it. That is, A's default constructor is accessible from within B, yet it is not accessible from outside (no one can use A's default constructor from outside to construct an instance of B).
Another way to look at it is to ask, what is something frustrating about constructors and inheritance in C++? A common answer from some people (including myself) would be that there is no automatic facility which allows "pass-through" construction of base classes taking arguments from derived class constructors without explicitly declaring and defining the latter.
Without long delay, here the code which I have no clue why it does what it does:
#include <iostream>
class A {
private:
void print() { std::cout << "A.print() called" << std::endl; };
public:
template<typename Foo>
class B; //NOTE: no friend!
public:
A();
B<double>* bd;
B<int>* bi;
};
template<typename Foo>
class A::B{
A* callback;
public:
B(A* a):callback(a){};
void print() { callback->print(); }; // Why is this working ???
};
A::A():bd(new B<double>(this)),bi(new B<int>(this)){}
int main(int argc, char **argv)
{
A a;
// a.print(); // error: ‘void A::print()’ is private
a.bd->print();
a.bi->print();
A::B<char> c(&a);
c.print();
A::B<double> d = *a.bd;
d.print();
return 0;
}
Well, it creates this ouput:
A.print() called
A.print() called
A.print() called
A.print() called
But why?
Background
I initially started my journey down the rabbit hole when I encountered a problem which I through to have to do with friends. So I read friend declaration not forward declaring (and the mentioned answers here and here). So while trying to set up an easy example (the result of which you see above), I found that I actually don't seem to need friend at all.
Question
So here is the bottom line question: Why does an instance of A::B have access to A's private function A::print()? (although I do realize that I might misunderstand what my children are--children as opposed to base vs. derived)
because nested class is a member of the enclosing class
standard $11.7.1
"A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed"
and the usual access rules specify that:
"A member of a class can also access all the names to which the class has access..."
specific examples has been given in the standard:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
}
A nested class (or inner class) has access to the privates of the class it is nested within. It is in some sense already friends with that class. It is similar to the way that any A object has access to the privates of any other A object.
You use friend for classes that are defined outside of your class that you want to access its privates. Here's a simple example of this:
struct B;
class A
{
int x;
friend struct B;
};
struct B
{
void someFunc() {
A a;
a.x = 5;
}
};
int main(int argc, const char* argv[])
{
B b;
b.someFunc();
return 0;
}
Without making B a friend of A, it would not be able to access A's member x.
I am getting problems in initializing the nested class constructor.
Here is my code:
#include <iostream>
using namespace std;
class a
{
public:
class b
{
public:
b(char str[45])
{
cout<<str;
}
}title;
}document;
int main()
{
document.title("Hello World"); //Error in this line
return 0;
}
The error I get is:
fun.cpp:21:30: error: no match for call to '(a::b)'
You probably want something like:
class a
{
public:
a():title(b("")) {}
//....
};
This is because title is already a member of a, however you don't have a default constructor for it. Either write a default constructor or initialize it in the initialization list.
You have to either make your data member a pointer, or you can only call the data member's constructor from the initialiser list of the construtor of the class it is a member of (in this case, a)
This:
document.title("Hello World");
is not "initializing the nested class"; it's attempting to call operator() on the object.
The nested object is already initialised when you create document. Except that it's not, because you've provided no default constructor.
So what do you have here:
class A {
B title;
}
Without defining constructor for class A (as Luchian Grigore shown) title will be initialized as: B title();
You can work that around by:
A::A():title(B("Hello world"))
// Or by adding non parametric constructor:
class B {
B(){
}
B( const char *str){
}
}
Object title (in document) is already initialized and you cannot call constructor anymore, but you still may use syntax: document.title(...) by declaring and defining operator() but it won't be constructor anymore:
class B {
const B& operator()(const char *str){
cout << str;
return *this;
}
}
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
Can the first constructor call the second one?
Not before C++11.
Extract the common functionality into a separate function instead. I usually name this function construct().
The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.
A destructor, however, can be called without a problem.
Not before C++0x, no.
BUT, just out of academic interest I've come up with a really horrible way* to do it using a placement operator "new" (someone care to point out how portable this is?)
#include <new>
#include <iostream>
class A
{
public:
A(int i, int j)
: i_(i), j_(j) { }
A(int i)
{ new (this) A(i, 13); }
int i_,j_;
};
int
main() {
A a1(10,11), a2(10);
std::cout
<< a1.i_ << ", "
<< a1.j_ << std::endl
<< a2.i_ << ", "
<< a2.j_ << std::endl;
return 0;
}
*Hell no, I don't write this in the production code.
The answer is in fact "yes", but as others have suggested, it doesn't do what you want. You can of course use the constructor of a base class, either implicitly or explicitly:
struct B {
B() {}
B( int x ) {}
};
struct A : public B {
A() {} // calls B() implicitly
A( int a, int b ) : B( b ) {} // calls B(int) explicitly
};
Not directly. There are a few ways to work around this.
From the initializer list of your class' constructor, you can call a constructor on any base class, and on all member variables.
So you can usually refactor your class and split it into several smaller ones to solve the problem. The commonly executed code can be placed in a member object or perhaps a base class. Then each of the main class' constructors just have to decide which construcotr to use to initialize that member.
class B {
B() { }
B(int b) { DoSomething(); }
}
class A{
A(int a = 5) : b(a) { } // call B's constructor which does something
A() : b() {} // call B's constructor which does nothing
B b;
};
This is an old question; however,
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
could be
class A{
A(int a = 5){
*this = A();
DoSomething();
}
A(){...}
}
As pointed out by Pavel Radzivilovsky in his answer, since C++ 11, it is possible. It is the same syntax as for explicitely calling the parent's class constructor from a child class. This is useful when a class needs to have multiple constructors (say, a default constructor and a constructor with attribute initialization) but some operations have to be done in all cases. This allows to avoid code repetitions.
Here is an example:
class A
{
public:
A()
{
foo();
}
A(Attribute attribute) : A()
{
this->attribute = attribute;
}
//------ some other code --------
private:
Attribute attribute;
void foo()
{...}
//------ some other code -------
};
In this simple example, I assume that the function foo() needs to be called in all cases for the object to be correctly initialized. With this syntax, if the second constructor (with attribute initialization) is called, it will first perform the operations in the default constructor before executing the instructions in the attribute-initialization constructor.
It can also be done the other way around: the default constructor can call another constructor with default parameters.
Before C++ 11, it was necessary to duplicate the common instructions of all constructors or define methods that do the actual object initialization.