Why I can use the class name as a function name? - c++

As far as I know in C++ we cannot use the same identifier for another declaration:
int x;
char x; // compile-time error: redefinition.
But here is an example where I was messing with classes:
#include "stdafx.h"
#include <iostream>
#include <vector>
class A {
public:
A(int);
void print()const;
friend std::ostream& operator << (std::ostream& out, A& rhs);
private:
int value1;
};
std::ostream& operator << (std::ostream& out, A& rhs) {
out << "rhs.value1 = " << rhs.value1 << std::endl;
return out;
}
A::A(int x) : value1(x) { std::cout << "ctor A(x)" << std::endl; }
void A::print()const {
std::cout << "value1: " << value1 << std::endl;
}
int A(int x) {
std::cout << "inside A(int x)" << std::endl;
return x;
}
int main(){
class A a { 0 };
a = A(7);
a.print();
std::cout << A(7) << std::endl;
std::cout << A(5) << std::endl; // here if I comment out the function a it is ok as long as I overloaded the insertion operator
// and if I add the function A it hides the insertion operator!
std::cout << std::endl;
std::cin.get();
return 0;
}
So as you can see above I must add the keyword class whenever I declare an object of class Aotherwise I get a compile-time error. Why?
Is the expression a = A(7); a function call and the return value is passed to the constructor of class A that takes an integer. Or simply no function call but only ctor call?

From my point of view, you have a class A and a function A, so you have to point out A is a class or a function that's why you have to add "class" when you declare an object of A.
According to the following code, two classes, A and B, are defined, they are exactly same, but A can be a function or a class, so when you declare a object A, you have to add a "class" before A, while declare a object of B is no need to add a "class"
For the second question, first function A is called, and its return value is used to construct object a. You can see first x=7 is in the function A, and ctor x=8 because the function return x+1.
The output:
ctor A(x) x=0
inside A(int x) x=7
ctor A(x) x=8
ctor B(x)
The test code:
#include <iostream>
#include <vector>
class A {
public:
A(int);
private:
int value1;
};
class B {
public:
B(int);
private:
int value1;
};
B::B(int x) : value1(x) { std::cout << "ctor B(x)" << std::endl; }
A::A(int x) : value1(x) { std::cout << "ctor A(x) x=" << x <<std::endl; }
int A(int x) {
std::cout << "inside A(int x) x=" << x << std::endl;
x=x+1;
return x;
}
int main(){
class A a(0);
a = A(7);
B b(0);
return 0;
}

Related

why does it say that class myPair has no member of out? it works well when I define the function in the class

#include <iostream>
using namespace std;
class myPair {
private:
int x, y;
public:
myPair(int x = 3, int y = 2) {};
friend void out(string a) {};
};
void out(string a) {
myPair p;
cout << a << "x equals " << p.x << "and " << a << "y equals " << p.y;
};
int main() {
myPair A(5, 3);
A.out("A : ");
}
this code is supposed to print out info about myPair class object but for some reason compiler tells me that there is not any member with the name of out() in myPair
The behaviour of your code is undefined. This is because you don't set the member variables in myPair and then subsequently read their values.
Rather than your out function, it's idiomatic C++ to define the << operator for ostream and your class. In that way you can use it directly in a cout statement. Here are the changes, including the fix to your constructor:
#include <iostream>
class myPair {
private:
int x;
int y;
public:
myPair(int x = 3, int y = 2) : x(x), y(y) /*there is no ambiguity here bizarrely*/
{
};
friend std::ostream& operator<<(std::ostream& os, const myPair& p);
};
std::ostream& operator<<(std::ostream& os, const myPair& p){
os << "x equals " << p.x << " and y equals " << p.y;
return os;
}
int main() {
myPair A(5, 3);
std::cout << "A: " << A;
}
You declare a function friend to the class so that this function can access the private data members of the class. And remember you cannot call friend function like A.out as it just an external function with special privileges and does not have this pointer. So it cannot be called that way.
And further, when you put {} in the front of the function signatures it becomes a definition. So You have to obey ODR(One Definition Rule). While declaring the friend function you cannot put {} otherwise you will get an error.
One more thing your constructor is not constructing the object properly, it is just taking parameters and doing nothing.
To let your friend do something to an object is to pass the object in the friend function.
You can see below the correct version of your code:
#include <iostream>
using namespace std;
class myPair {
private:
int x, y;
public:
myPair(int _x = 3, int _y = 2): x(_x), y(_y) {};
friend void out(const string& a, myPair& p);
};
void out(const string& a, myPair& p) {
//myPair p;
cout << a << "x equals " << p.x << "and " << a << "y equals " << p.y;
};
int main() {
myPair A(5, 3);
out("A : ", A);
}
This is not a method, so You need to pass your object into out("", myPair). It works as expected.
You are declaring out as a friend function not a member. So your code should look like,
#include <iostream>
using namespace std;
class myPair {
private:
int x, y;
public:
myPair(int x = 3, int y = 2) : x(x), y(y){};
void out(string);
};
void myPair::out(string a) {
cout << a << "x equals " << this->x << "and " << a << "y equals " << this->y;
};
int main() {
myPair A(5, 3);
A.out("A : ");
}
If you want friend functions you can do,
#include <iostream>
using namespace std;
class myPair {
private:
int x, y;
public:
myPair(int x = 3, int y = 2) : x(x), y(y) {};
friend void out(myPair p, string a);
};
void out(myPair p, string a) {
cout << a << "x equals " << p.x << "and " << a << "y equals " << p.y;
};
int main() {
myPair A(5, 3);
out(A, "A : ");
}

using overloaded << operator in another << overload in a different class

So here's the problem. I have a class B where I have overloaded the << operator and a class A where the << operator is also overloaded. However, the << overload in class B doesn't seem to be working in the << overload in class A. It simply returns the address of b as if the << overload in class B doesn't exist.
Any help would be very appreciated
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) {
this->b = b;
this->x = 0;
}
friend ostream& operator<<(ostream& os, A& a)
{
os << a.b << endl; //this doesnt work <============
os << "this is a " << a.x;
return os;
}
private:
int x;
B* b;
};
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << *a << "inside a "<< endl;
cout << *b << "inside b " <<endl;
}
os << a.b // ...
a.b is not a B, for which you defined an overload, look closer at your code:
class A {
private:
B* b;
};
That's a B *, and not a B, and no overload exists for that.
If you want to call the overload here, use os << (*a.b) // ...;

C++ class friendship

I am writing code to access private members of a class through another friend class. The below code works
// Example program
#include <iostream>
#include <string>
using namespace std;
class Foo
{
private:
int a;
protected:
public:
friend class Bar;
Foo(int x)
{
a = x ;
}
};
class Bar
{
private:
protected:
public:
int b;
Bar(Foo& f)
{
b = f.a;
cout << "f.a is " << f.a << endl;
}
};
int main()
{
Foo foo(5);
Bar bar(foo);
cout << "Value of variable b is " << bar.b << endl;
}
Above code works fine. However, if I want to access a private variable of Foo through a function in friend class Bar, I am unable to. See code below
#include <iostream>
#include <string>
using namespace std;
class Foo
{
private:
int a;
protected:
public:
friend class Bar;
Foo(int x)
{
a = x ;
}
};
class Bar
{
private:
protected:
public:
int b;
Bar(Foo& f)
{
b = f.a;
}
void printvariable(void)
{
cout << "f.a is " << f.a << endl;
}
};
int main()
{
Foo foo(5);
Bar bar(foo);
cout << "Value of variable b is " << bar.b << endl;
}
I totally understand why execution fails on the
void printvariable(void)
{
cout << "f.a is " << f.a << endl;
}
function since f is not in scope for the function. However, since I am passing Foo f in the constructor for Bar b, I am hoping to write code that will allow me to access members in Foo without passing Foo f to the function printvariable() again.
What is the most efficient way to write this code?
You can keep the reference to f. The code should be:
class Bar
{
private:
protected:
public:
int b;
Foo& f_ref;
Bar(Foo& f)
:f_ref(f)
{
b = f.a;
}
void printvariable(void)
{
cout << "f.a is " << f_ref.a << endl;
}
};
TEST!
You can do it like this, but if I were you I'd write some getters, also – class friendship isn't really recommended.
class Bar {
public:
Foo& ref;
Bar(Foo& f)
: ref { f }
{ }
void printvariable() {
cout << "f.a is " << ref.a << endl;
}
};
Btw there's no reason to add void in brackets in C++, it lost its meaning from C and has no effect by now.
You are wrong in one point. You are indeed passing a reference to f in the ctor, but the constructor and whole class Bar does not remember a whole object of f. In your original code, the constructor only makes the Bar object remember the int a part of the object, so only that little bit is later accessible:
class Foo
{
...
friend class Bar;
...
};
class Bar
{
...
int b;
Bar(Foo& f)
{
b = f.a; // <=--- HERE
}
void printvariable(void)
{
cout << "f.a is " << b << endl; // <-- now it refers B
}
Please note how your ctor of Bar only reads f.a and stores it in b. From now on, the Bar object only remembers b and that's all. You can freely access the b in printvariable. However, it will not be the a-taken-from-f. It will be b, that was set to the same value as f.a during constructor. Since that point of time, b and f.a are totally separate. That's how value copying works.
To make Bar remember whole f, you have to, well, remember whole f:
class Bar
{
...
Foo wholeThing;
Bar(Foo& f)
{
wholeThing = f; // <=--- HERE
}
void printvariable(void)
{
cout << "f.a is " << wholeThing.a << endl;
}
However, again, there's a catch: now since wholeThing is of type Foo, the constructor will actually make a copy of that object during wholeThing=f. Just the same as it was when b=f.a, but now it remembers a copy of whole f.
Of course, it's only matter of type. You can store a reference instead of whole-Foo, but it needs a bit different initialization syntax:
class Bar
{
...
Foo& wholeThing;
Bar(Foo& f) :
wholeThing(f) // <=--- HERE
{
// <=--- empty
}
void printvariable(void)
{
cout << "f.a is " << wholeThing.a << endl;
}

conditional operator can return reference?

I came across a line of code and never thought it might work well. I thought the conditional operator return value and does not work with reference.
Some pseudo code:
#include <iostream>
using namespace std;
class A {
public:
A(int input) : v(input) {};
void print() const { cout << "print: " << v << " # " << this << endl; }
int v;
private:
//A A(const A&);
//A operator=(const A&);
};
class C {
public:
C(int in1, int in2): a(in1), b(in2) {}
const A& getA() { return a;}
const A& getB() { return b;}
A a;
A b;
};
int main() {
bool test = false;
C c(1,2);
cout << "A # " << &(c.getA()) << endl;
cout << "B # " << &(c.getB()) << endl;
(test ? c.getA() : c.getB()).print(); // its working
}
Can someone explain? Thx.
Your assumption about the conditional operator is wrong. The type of the expression is whatever type the expressions c.getA() and c.getB() have, if they have the same type, and if they denote lvalues, then so does the entire expression. (The exact rules are in §5.16 of the C++ standard.)
You can even do this:
(condition? a: b) = value;
to conditionally set either a or b to value. Note that this is C++-specific; in C, the conditional operator does not denote an lvalue.

How do I invoke the move constructor?

In the code show below, how do I assign rvalue to an object A in function main?
#include <iostream>
using namespace std;
class A
{
public:
int* x;
A(int arg) : x(new int(arg)) { cout << "ctor" << endl;}
A(const A& RVal) {
x = new int(*RVal.x);
cout << "copy ctor" << endl;
}
A(A&& RVal) {
this->x = new int(*RVal.x);
cout << "move ctor" << endl;
}
~A()
{
delete x;
}
};
int main()
{
A a(8);
A b = a;
A&& c = A(4); // it does not call move ctor? why?
cin.ignore();
return 0;
}
Thanks.
Any named instance is l-value.
Examples of code with move constructor:
void foo(A&& value)
{
A b(std::move(value)); //move ctr
}
int main()
{
A c(5); // ctor
A cc(std::move(c)); // move ctor
foo(A(4));
}