Friend function and method with the same name - c++

The following classes definitions declare a friend function providing an inline definition for it. I was trying to invoke the friend function from a class method with the same name of the friend function, but in order to make it work I have to access it from the enclosing namespace (which also requires a forward declaration, class C below). Why the name lookup works for class A and it doesn't work in class B? Note that the parameters of B::swap are different from those of its friend function.
#include <utility>
struct A {
A(int x) : v{ x } {}
friend void swap(A& x, A& y) { std::swap(x.v, y.v); }
void swapm(A& other) { swap(*this, other); }
private:
int v;
};
struct B {
B(int x) : v{ x } {}
friend void swap(B& x, B& y) { std::swap(x.v, y.v); }
void swap(B& other) { swap(*this, other); } // <-- This doesn't compile
private:
int v;
};
struct C;
void swap(C& x, C& y);
struct C {
C(int x) : v{ x } {}
friend void swap(C& x, C& y) { std::swap(x.v, y.v); }
void swap(C& other) { ::swap(*this, other); }
private:
int v;
};
int main()
{
A a1{ 1 }, a2{ 2 }; swap(a1, a2); a1.swapm(a2);
B b1{ 3 }, b2{ 4 }; swap(b1, b2); b1.swap(b2);
C c1{ 5 }, c2{ 6 }; swap(c1, c2); c1.swap(c2);
}

Whether it's a good idea or not, here's an explanation of why it's failing:
The compiler uses several different phases of processing to figure out what your program says. The reason that class B doesn't compile is because the failure that's occurring happens before the friend would be noticed. Let me explain:
When the compiler gets to the point where it's trying to figure out what swap means, it does a name lookup. It uses specific rules that specify where it should look. This is simplified, but basically it first looks for symbols defined in local scope, then in class scope, and then in enclosing (namespace, etc) scopes. It finds the one defined in class scope, and stops looking. That swap does not take those 2 parameters, so it the compilation fails.
The friend declaration, which allows the free function to access B's internals, acts as an additional declaration for the swap function that you've declared in the global namespace. These declarations would be considered by the compiler if it got to the point in name lookup where it was considering functions in the global namespace. In class B, the compiler has already stopped processing before it gets to this stage. (And the friend declaration would be necessary in an even later phase, when the compiler is working on compiling a version of the swap function that works with B objects, and wants to figure out, "in this function called swap that can take these 2 parameters; can I access B's internals?")
In class A, you're using a different name. The name lookup phase doesn't succeed until it locates your free swap function. In class C, you've given the name-lookup specific instructions, "hey, when you're looking up swap, look in global-namespace scope, and ignore the ones in local- and class-scope that you might find."
(Note: description of name-lookup and friend updated after #PeteBecker's comment.)

inline friend? Why not static in this case? And not friend? And then create a global one that calls the static. For me, this is a bad design more than an actual problem.
The method swap should be the one doing the work instead of the friend (because no need for a friend anymore):
struct C {
C(int x) : v{ x } {}
void swap(C& other) { std::swap(this->v, other.v); }
private:
int v;
};
void swap(C& x, C& y)
{
x.swap(y);
}

Related

Can we declare constructor before member variables?

Can the constructer declared before the member variable alter its value?
I thought only the code below works,
struct test {
int a;
test(int t): a(t) {}
};
but I found the code below also works.
struct test {
test(int t): a(t) {}
int a;
};
Usually, in function, we cannot use the variable that is not declared. Why the code above is OK?
Actually in C++ there's an exception that there's no need for forward declaration of functions and variable of a class/struct.
You can see my such examples on the internet like this:
class foo
{
public:
foo(int x) : my_var(x) {}
private:
int my_var;
};
The above is 100% valid.
You can also call a function of a class before it is defined like:
class bar
{
public:
bar()
{
this->my_below_func();
}
int my_below_func()
{
return 1;
}
};
Always remember that these tricks aren't going to work outside C++ classes/structs, you will need forward declaration of your functions and variables.

C++ member function as friend

I have 2 Classes Namely A and B with following independent declaration
class A {
private:
std::vector<B> vec = {B("X","Y")};
public:
A();
void clear(std::vector<B>::size_type index);
};
class B {
private:
std::string m_first;
std::string m_second;
public:
B() = default;
B(std::string first, std::string second) : m_first(first), m_second(second) {}
// I want the friend below - how to do it?
friend void A::clear(std::vector<B>::size_type index);
};
I want to declare void A::clear(std::vector<B>::size_type index) to be friend of class B. Is it possible in C++? I cannot do forward declaration of B for A as A needs to see B's constructor with 2 arguments.
I'm 99% sure that your requirement to have A::clear as a friend of B is a case of too tight of a coupling. This is friendship misuse. Think of another way of doing it.
Please edit the question and provide the reason why you think you need that friendship. What is exactly the relationship between these classes, what's the use case? Convince us that there's a need for friendship, because I don't see it.
And the best I can tell the signature of B's constructor is wasteful in copying the arguments (by taking them by value). These arguments should be taken by const reference, unless you need a copy to modify within the method/constructor. I've fixed it below.
A needs to see B constructor with 2 arguments .
It doesn't! A doesn't. Only A's constructor does:
#pragma once
#include <string>
#include <vector>
class B;
class A {
private:
std::vector<B> vec;
public:
A();
void clear(std::vector<B>::size_type index);
};
class B {
private:
std::string m_first;
std::string m_second;
public:
B() = default;
B(const std::string &first, const std::string &second) :
m_first(first),m_second(second) {}
friend void A::clear(std::vector<B>::size_type index);
};
inline A::A() : vec{ B("X", "Y") } {}
Another trick is to put A inside of B. But it's wholly unnecessary.
#pragma once
#include <string>
#include <vector>
class B {
private:
std::string m_first;
std::string m_second;
public:
class A {
private:
std::vector<B> vec = {B("X","Y")};
public:
void clear(const std::vector<B>::size_type &index);
};
B() = default;
B(const std::string &first, const std::string &second) :
m_first(first),m_second(second) {}
friend void A::clear(const std::vector<B>::size_type &index);
};
using A = B::A;
You've set things up so the class A needs to be defined before B (so B can declare a member of A as a friend) but simultaneously B needs to be defined before A (so the vec member of A can be initialised using the constructor of B).
This is a circular dependency (definition of A must be before definition of B which must be before the definition of A - ad infinitum).
Declaring a member of a class as a friend is not possible unless that class has been previously defined.
You need to break that circular dependency - either by not having A::clear() as a friend of B, or by not initialising the vec member of A within the class definition (which means you then need to initialise vec solely in the constructor of A).
Alternatively, it is possible to declare A as friend of B without A being previously defined (i.e. a previous declaration of A is sufficient, without making it a definition). So an alternative may be to declare A as a friend of B rather than only A::clear().
This means that B must be defined before A. B can be defined without visibility of the definition of A.

Should this -> operator be used in the case where internal class member is invoked in C++?

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.

C++ friend function hidden by class function?

Minimal example:
class A
{
friend void swap(A& first, A& second) {}
void swap(A& other) {}
void call_swap(A& other)
{
swap(*this, other);
}
};
int main() { return 0; }
g++ 4.7 says:
friend.cpp: In member function ‘void A::call_swap(A&)’:
friend.cpp:7:20: error: no matching function for call to ‘A::swap(A&, A&)’
friend.cpp:7:20: note: candidate is:
friend.cpp:4:7: note: void A::swap(A&)
friend.cpp:4:7: note: candidate expects 1 argument, 2 provided
Outcomment line 4:
// void swap(A& other) {}
...and it works fine. Why, and how to fix this, if I want to keep both variants of my swap function?
I believe it is because the compiler is trying to find the function within the class. This should be a minimalistic change to make it work (it works in Visual Studio 2012):
class A; // this and the next line are not needed in VS2012, but
void swap(A& first, A& second); // will make the code compile in g++ and clang++
class A
{
friend void swap(A& first, A& second) {}
void swap(A& other) {}
void call_swap(A& other)
{
::swap(*this, other); // note the scope operator
}
};
int main() { return 0; }
As a workaround, you can declare a static version of swap. Then, you can declare the friend version to call the static version.
class A
{
public:
friend void swap(A& first, A& second) { A::swap(first, second); }
private:
static void swap(A& first, A& second) {}
void swap(A& other) {}
void call_swap(A& other)
{
swap(*this, other);
}
};
int main () {
A a, b;
swap(a, b);
}
Why
Inside the class, names scoped within the class hide those in the surrounding namespace; so the friend (whose name is scoped in the namespace, but not directly accessible there) is hidden by the member (scoped in the class) and not available as a potential overload here. (Update: or perhaps it's a bit more complicated than that, as mentioned in the comments. The scope and name lookup rules are a bit hard to follow, especially when friends are involved).
how to fix this, if I want to keep both variants of my swap function?
There's no perfect solution. If the functions both do the same thing, then just use the member from other member functions. If you declare the friend outside the class definition, then it's accessible as ::swap; but this is a bit fragile if you put the class in a different namespace. (Update: or use a static member function as suggested by this answer; I didn't think of that).
Keep to the standard swap idiom, and you won't have a problem:
void call_swap(A& other) {
using std::swap;
swap(*this, other);
}
Or use the Boost.Swap wrapper:
void call_swap(A& other) {
boost::swap(*this, other);
}
This is pretty much equivalent to #Juan's solution, except you're not writing the helper yourself.
You can also use a helper function, as in this case
template<class T>
void swap_elems(T& lhs, T& rhs)
{
using namespace std;
swap(lhs, rhs);
}
class A
{
friend void swap(A& first, A& second) { first.swap(second); }
public:
void swap(A& other) {}
void call_swap(A& other)
{
swap_elems(*this, other);
}
};
What you're observing here is that in absence of a previous declaration of a friend function, friendship within a class injects the name into the enclosing namespace, but NOT into the class scope. The only thing that happens at class scope is that the function named is granted access to private attributes.
This leaves only one swap function in the class scope (the member with one parameter) so that's the only candidate overload. Once you've found a candidate even if overload resolution fails you will never try another enclosing scope (shadowing).
If you really need both versions (and step back to make sure you do), put the implementation into a function like swap_impl which you call from the friend and the member.

Can I call a constructor from another constructor (do constructor chaining) in C++?

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 :)