Suppose I have a class Foo, with a member variable that is a std::vector of floats, bar. I then create an instance of Foo, called foo. Let's say that I do not know the length of bar before the program runs, but at the point when foo's constructor is called, I know that it's length should be x.
There are three ways I can think of to initialize the length of bar, and I'm just wondering which of the three most people tend to use. I have ranked them in order of what I would consider to be "best practice", but I'm more curious about what method people "actually" use in practice. Sometimes I use methods which make the code clearer to follow, rather than necessarily following best practice...
bar is a private member, and I resize it during foo's constructor, e.g. Foo foo(x){bar.resize(x)};
bar is a private member, and I call foo.ResizeBar(x) which resizes bar internally, after creating foo.
bar is a public member, and I call foo.bar.resize(x), after creating foo.
Or, in code:
1.
class Foo
{
private:
std::vector<float> bar;
public:
Foo(int x)
{
bar.resize(x);
};
};
int main()
{
Foo foo(100);
return 0;
}
2.
class Foo
{
private:
std::vector<float> bar;
public:
Foo()
{
};
void ResizeBar(int x)
{
bar.resize(x);
};
};
int main()
{
Foo foo;
foo.ResizeBar(100);
return 0;
}
3.
class Foo
{
public:
std::vector<float> bar;
Foo()
{
};
};
int main()
{
Foo foo;
foo.bar.resize(100);
return 0;
}
The problem with all three of your methods is that you're needlessly invoking the default initializer for your vector, and then modifying the already initialized vector to suit your needs.
You should be invoking the correct initializer using the initializer list:
Foo::Foo(std::size_t x) : bar(x, 0) { }
The best method is not in the list of options you posted. The best method is to initialize bar using member initializer lists.
Foo::Foo(int x) : bar(x) {}
This question already has answers here:
What are the differences between struct and class in C++?
(30 answers)
Closed 8 years ago.
For classes, you could just say:
class Test{
int a;
Test(int a);
}
Test::Test(int a) {
this->a=a;
}
Function names get "classname::" in front of them when declared outside of class.
How would I do this for structs?
struct Test {
int a;
Test(int a);
}
How would I write the function for this struct Test outside of struct declaration so that it can be only be called by a Test struct?
Same way. Difference between struct and class in C++ is only default visibility of members (private for class, public for struct).
Actually, it's not just function, it's constructor of class/struct Test.
In C++, structs are essentially the same as classes except for their default protection levels: classes default to private, structs to public. To define that function outside of the struct so that it can only be called from a member, declare it as private, then define it as normal:
struct Test {
private:
int a;
Test(int a);
};
Test::Test(int a) {
this->a=a;
}
Additionally, instead of modifying the a member in the constructor body like that, you should use an initializer list. This sets the value of the member before the instance is fully constructed. It's not so important with just an int, but it's a good practice to get in to.
struct Test {
private:
Test(int a) : a(a) {}
int a;
};
How would I write the function for this struct Test outside of struct declaration
Do exactly what you did for the first one. Both are class types, whether you use the class or struct keyword to introduce them.
The only difference is the default accessibility of members and base classes: private if you use class, and public if you use struct.
so that it can be only be called by a Test struct?
If you mean that you want it to be private (as it is in the first example), then you'll have to do so explicitly, since accessibility defaults to public:
struct Test {
int a;
private:
Test(int a);
};
Personally, I'd use the more conventional class if there's anything non-public.
ForEveR is right. Just like in the question you can have a structure member defined like:
struct Test{
int a;
Test(int a);
};
Test::Test(int a) {
this->a=a;
}
point to note, struct members are public by default. class memebers are private by default.
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 want to implement the Visitor pattern in C++ like this:
class Visitor{
public:
virtual ~Visitor();
virtual void visit(C & t)=0;
};
class V : public Visitor{
public:
void visit(C &c);
};
class C{
public:
void accept(Visitor &v){ v.visit(*this); }
};
But the compiler complains abount 2 syntax errors:
Unknown identifier C and Visitor.
Where is the problem?
At the moment the compiler sees
virtual void visit(C & t)=0;
name C is unknown.
You need to forward-declare class C before Visitor
class C;
class Visitor{
...
}
In the C++ language the compiler will not look ahead for names that are yet to be defined or, to say it better, sometimes it does and sometimes it doesn't.
You can say for example
struct Foo
{
Foo(int x) : m_x(x) { }
int m_x;
};
and the compiler will not complain even if you used m_x before defining what m_x is, but however at the module level this look ahead is not present:
struct Foo
{
Bar *p; // Error, Compiler doesn't know what Bar is
};
// Too late, the compiler is not going to read down here while
// analyzing Foo.
struct Bar
{
int x;
};
How do you solve cases in which you need to use something before defining it? By using a special "forward declaration", in which you only state that there will be something with that name and you define later what it is in the specific... for example
struct Foo; // There will be a struct Foo defined somewhere
struct Bar
{
Foo *p; // Fine, even if the compiler doesn't really know Foo
};
struct Foo
{
Bar *q; // Fine and no forward needed... Bar is known at this point
};
More or less the rule is: in a single class all methods can see all other methods and all members even if they are defined later in the class, at a module level instead every name must be known before it can be used.
Sometimes a more complex pattern is needed, like
struct Foo;
struct Bar
{
void doit(Bar x);
};
struct Foo
{
void doit_too(Foo x);
};
void Foo::doit(Bar x) { ... }
void Bar::doit_too(Foo x) { ... }
In the last case you are forced to put the implementation of both methods after the declarations of both classes because just knowing that Foo is a class is not enough to be able to compile a copy operation (note the parameter in the methods has been passed by value, not by pointer or reference).
At the fourth line, nobody knows what C is. It is an unknown identifier.
This makes the definition of Visitor not valid, hence when you try to use your Visitor later another error occurs.
Problem is Class C is not defined at the point Visitor uses it. Either move it to the top (class C that is) or:
class C;
Add the above forward declaration at top of file. Since you only use it as a reference param, this should suffice.
As a C# developer I'm used to running through constructors:
class Test {
public Test() {
DoSomething();
}
public Test(int count) : this() {
DoSomethingWithCount(count);
}
public Test(int count, string name) : this(count) {
DoSomethingWithName(name);
}
}
Is there a way to do this in C++?
I tried calling the Class name and using the 'this' keyword, but both fail.
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:
You can combine two (or more) constructors via default parameters:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};
Use an init method to share common code:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
// ...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
// ...
}
Foo::Foo(char x, int y)
{
init(x, y);
// ...
}
void Foo::init(char x, int y)
{
// ...
}
See the C++FAQ entry for reference.
Yes and No, depending on which version of C++.
In C++03, you can't call one constructor from another (called a delegating constructor).
This changed in C++11 (aka C++0x), which added support for the following syntax:
(example taken from Wikipedia)
class SomeType
{
int number;
public:
SomeType(int newNumber) : number(newNumber) {}
SomeType() : SomeType(42) {}
};
I believe you can call a constructor from a constructor. It will compile and run. I recently saw someone do this and it ran on both Windows and Linux.
It just doesn't do what you want. The inner constructor will construct a temporary local object which gets deleted once the outer constructor returns. They would have to be different constructors as well or you would create a recursive call.
Ref: https://isocpp.org/wiki/faq/ctors#init-methods
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
It is worth pointing out that you can call the constructor of a parent class in your constructor e.g.:
class A { /* ... */ };
class B : public A
{
B() : A()
{
// ...
}
};
But, no, you can't call another constructor of the same class upto C++03.
In C++11, a constructor can call another constructor overload:
class Foo {
int d;
public:
Foo (int i) : d(i) {}
Foo () : Foo(42) {} //New to C++11
};
Additionally, members can be initialized like this as well.
class Foo {
int d = 5;
public:
Foo (int i) : d(i) {}
};
This should eliminate the need to create the initialization helper method. And it is still recommended not calling any virtual functions in the constructors or destructors to avoid using any members that might not be initialized.
If you want to be evil, you can use the in-place "new" operator:
class Foo() {
Foo() { /* default constructor deliciousness */ }
Foo(Bar myParam) {
new (this) Foo();
/* bar your param all night long */
}
};
Seems to work for me.
edit
As #ElvedinHamzagic points out, if Foo contained an object which allocated memory, that object might not be freed. This complicates things further.
A more general example:
class Foo() {
private:
std::vector<int> Stuff;
public:
Foo()
: Stuff(42)
{
/* default constructor deliciousness */
}
Foo(Bar myParam)
{
this->~Foo();
new (this) Foo();
/* bar your param all night long */
}
};
Looks a bit less elegant, for sure. #JohnIdol's solution is much better.
Simply put, you cannot before C++11.
C++11 introduces delegating constructors:
Delegating constructor
If the name of the class itself appears as class-or-identifier in the
member initializer list, then the list must consist of that one member
initializer only; such constructor is known as the delegating
constructor, and the constructor selected by the only member of the
initializer list is the target constructor
In this case, the target constructor is selected by overload
resolution and executed first, then the control returns to the
delegating constructor and its body is executed.
Delegating constructors cannot be recursive.
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
};
Note that a delegating constructor is an all-or-nothing proposal; if a constructor delegates to another constructor, the calling constructor isn't allowed to have any other members in its initialization list. This makes sense if you think about initializing const/reference members once, and only once.
No, in C++ you cannot call a constructor from a constructor. What you can do, as warren pointed out, is:
Overload the constructor, using different signatures
Use default values on arguments, to make a "simpler" version available
Note that in the first case, you cannot reduce code duplication by calling one constructor from another. You can of course have a separate, private/protected, method that does all the initialization, and let the constructor mainly deal with argument handling.
Another option that has not been shown yet is to split your class into two, wrapping a lightweight interface class around your original class in order to achieve the effect you are looking for:
class Test_Base {
public Test_Base() {
DoSomething();
}
};
class Test : public Test_Base {
public Test() : Test_Base() {
}
public Test(int count) : Test_Base() {
DoSomethingWithCount(count);
}
};
This could get messy if you have many constructors that must call their "next level up" counterpart, but for a handful of constructors, it should be workable.
In Visual C++ you can also use this notation inside constructor: this->Classname::Classname(parameters of another constructor). See an example below:
class Vertex
{
private:
int x, y;
public:
Vertex(int xCoo, int yCoo): x(xCoo), y(yCoo) {}
Vertex()
{
this->Vertex::Vertex(-1, -1);
}
};
I don't know whether it works somewhere else, I only tested it in Visual C++ 2003 and 2008. You may also call several constructors this way, I suppose, just like in Java and C#.
P.S.: Frankly, I was surprised that this was not mentioned earlier.
This approach may work for some kinds of classes (when the assignment operator behaves 'well'):
Foo::Foo()
{
// do what every Foo is needing
...
}
Foo::Foo(char x)
{
*this = Foo();
// do the special things for a Foo with char
...
}
I would propose the use of a private friend method which implements the application logic of the constructor and is the called by the various constructors. Here is an example:
Assume we have a class called StreamArrayReader with some private fields:
private:
istream * in;
// More private fields
And we want to define the two constructors:
public:
StreamArrayReader(istream * in_stream);
StreamArrayReader(char * filepath);
// More constructors...
Where the second one simply makes use of the first one (and of course we don't want to duplicate the implementation of the former). Ideally, one would like to do something like:
StreamArrayReader::StreamArrayReader(istream * in_stream){
// Implementation
}
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
StreamArrayReader(&instream);
instream.close();
}
However, this is not allowed in C++. For that reason, we may define a private friend method as follows which implements what the first constructor is supposed to do:
private:
friend void init_stream_array_reader(StreamArrayReader *o, istream * is);
Now this method (because it's a friend) has access to the private fields of o. Then, the first constructor becomes:
StreamArrayReader::StreamArrayReader(istream * is) {
init_stream_array_reader(this, is);
}
Note that this does not create multiple copies for the newly created copies. The second one becomes:
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
init_stream_array_reader(this, &instream);
instream.close();
}
That is, instead of having one constructor calling another, both call a private friend!
If I understand your question correctly, you're asking if you can call multiple constructors in C++?
If that's what you're looking for, then no - that is not possible.
You certainly can have multiple constructors, each with unique argument signatures, and then call the one you want when you instantiate a new object.
You can even have one constructor with defaulted arguments on the end.
But you may not have multiple constructors, and then call each of them separately.
When calling a constructor it actually allocates memory, either from the stack or from the heap. So calling a constructor in another constructor creates a local copy. So we are modifying another object, not the one we are focusing on.
Would be more easy to test, than decide :)
Try this:
#include <iostream>
class A {
public:
A( int a) : m_a(a) {
std::cout << "A::Ctor" << std::endl;
}
~A() {
std::cout << "A::dtor" << std::endl;
}
public:
int m_a;
};
class B : public A {
public:
B( int a, int b) : m_b(b), A(a) {}
public:
int m_b;
};
int main() {
B b(9, 6);
std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;
return 0;
}
and compile it with 98 std:
g++ main.cpp -std=c++98 -o test_1
you will see:
A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor
so :)