Specific case of using virtual method [duplicate] - c++

This question already has answers here:
What is object slicing?
(18 answers)
Closed 5 years ago.
I have the following code which return "YXX".
I would like to know why the second print displays an 'X' whereas the key-word virtual is used in the class X. So the line tab[0] = y1 will be set tab[0] as an Y object and displays 'Y' due to the virtual method isn't it ?
#include <iostream>
class X {
public: virtual void f() const { std::cout << "X"; }
};
class Y : public X {
void f() const { std::cout << "Y"; }
};
void print(const X &x) { x.f(); }
int main() {
X tab[2];
Y y1;
tab[0] = y1;
print(y1);
print(tab[0]);
print(tab[1]);
std::cout << std::endl;
}

tab is an array of X objects, so when you assign the Y object to an element of tab it slices off the Y portions and you are left with just the X part.
Now, if you changed it to:
X * tab[2];
tab[0] = new X;
tab[1] = new Y;
print(*tab[0]);
print(*tab[1]);
It would not do any slicing and it would print XY

Related

Calling multiple function using object in one line [duplicate]

This question already has answers here:
Multiple dot operator (c++ class)
(1 answer)
Is there a way to call multiple functions on the same object with one line?
(6 answers)
Closed 3 months ago.
I was going through geeksforgeeks and found below code
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
This class seems okay for me. But the function call and its output seems bit confusing.
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Here, if I call setX() and setY() function in single line, then the output will be:
x = 10 y = 0
else, if I call those function as given below,
int main()
{
Test obj1;
obj1.setX(10);
obj1.setY(20);
obj1.print();
return 0;
}
then the output seems
x = 10 y = 20.
What is the difference between these two function call. Can someone explain using this pointer?
Thankyou in advance.

C++ - Is it possible to use the method of another class without inheritance?

I'm fairly nooby at C++ but have this question that I hope makes sense:
Can a method in class B call a method within class A under these conditions:
B cannot inherit from A
you cannot create an object of A within B
the method in A cannot be static
For example, can this be done by passing an object of A by reference to the method call of B.
My next question would be, what if an object of B was created WITHIN an object of A. How does A reference itself to pass to the method of object B?
An example of what I'm imagining:
class A;
class B
{
int x = 10;
int y = 10;
public:
DoThis(A* obj);
};
B::DoThis(A* obj)
{
obj->DoThat(int x, int y);
}
class A
{
public:
DoSomething();
DoThat(int x, int y);
};
A::DoSomething()
{
B objB;
objB.DoThis(this);
}
A::DoThat(int x, int y)
{
std::cout << x << y;
}
int main()
{
A* objA = new A;
objA->DoSomething();
}
The only problem is that your code contains numerous rudimentary errors, like lack of type specifiers in declarations, lack of terminating semicolons, wrong order (using a class A before it has been declared), mismatches between calls and declarations and such.
Here is a patch to fix the problems. I also added a , (comma space) between the two numbers being output, and a terminating newline.
--- dothis-ORIG.cc 2019-09-18 14:13:15.002235916 -0700
+++ dothis.cc 2019-09-18 14:16:56.548099037 -0700
## -1,32 +1,36 ##
+#include <iostream>
+
+class A;
+
class B
{
- x = 10;
- y = 10;
+ int x = 10;
+ int y = 10;
public:
- DoThis(A* obj);
-}
-
-B::DoThis(A* obj)
-{
- obj->DoThat(x, y)
-}
+ void DoThis(A* obj);
+};
class A
{
public:
- DoSomething();
- DoThat();
+ void DoSomething();
+ void DoThat(int x, int y);
+};
+
+void B::DoThis(A* obj)
+{
+ obj->DoThat(x, y);
}
-A::DoSomething()
+void A::DoSomething()
{
B objB;
objB.DoThis(this);
}
-A::DoThat(x, y)
+void A::DoThat(int x, int y)
{
- std::cout << x << y;
+ std::cout << x << ", " << y << std::endl;
}
int main()

Usage of this pointer in c++ [duplicate]

This question already has answers here:
What is the 'this' pointer?
(8 answers)
Closed 4 years ago.
I confused what does it mean this pointer and how it is used exactly. in the below examples give the same output. What is the difference putting reference operator(&) in the setX and setY functions?
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
With reference operator
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
When you return by value, as in
Test setX(int a) { x = a; return *this; }
then you return a copy of the object. And the copy is totally unrelated to the original object.
When you return a reference, you return a reference to the actual object, no copies are made.
And because of this difference the two programs you show should not produce the same output. The first should say that x is equal to 10 (because you set x on the obj1 object) but then you set y on the copy returned by setX, meaning that obj1.y will still be zero. See e.g. this example.

class member functions for C++ newbie [duplicate]

This question already has answers here:
Visual Studio 2015 “non-standard syntax; use '&' to create a pointer to member”
(3 answers)
Closed 5 years ago.
I'm new with C++ and I'm currently studying for exams, messing around with C++ in VisualStudio and experimenting a bit. Usuall I work with Java.
I wrote a simple class to see how and if things work:
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
};
I tried 2 simple member functions for x and y to just double the value stored in the x and y variables.
First I tried this:
void doubleX()
{
x *= 2;
};
void doubleY()
{
y *= 2;
};
Then I tried this:
void doubleX()
{
Point::x = 2 * Point::x;
};
void doubleY()
{
Point::y = 2 * Point2::y;
};
Both are put inside the class definition.
While building through VisualStudio it alwas gives me this error warning:
"Error C3867 'Point::doubleX': non-standard syntax; use '&' to create a pointer to member"
Tried to mess around with adress pointers as well but... I don't really have a clue.
I think I know how pointers basically work, but I have no idea how to use it for my case here.
Any quick solution and explanation to this problem?
Thanks in advance!
EDIT: here's my whole code, problem is in the main now
#include "stdafx.h"
#include <iostream>
using namespace std;
class Point
{
public:
int x;
int y;
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void doubleX()
{
x *= 2;
};
void doubleY()
{
y *= 2;
};
};
int main()
{
Point p(1,1);
int &x = p.x;
int &y = p.y;
cout << x << "|" << y;
p.doubleX; p.doubleY; //error message here
cout << x << "|" << y;
cin.get();
}
Maybe you didn't declare the member functions inside the class definition? Here is a full working example based on your class:
#include <iostream>
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void doubleX()
{
x *= 2; /* or this->x *= 2; */
}
void doubleY()
{
y *= 2;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
};
int main()
{
Point p(2, 3);
std::cout << "p.x = " << p.getX() << " | p.y = " << p.getY() << std::endl;
p.doubleX();
p.doubleY();
std::cout << "p.x = " << p.getX() << " | p.y = " << p.getY() << std::endl;
return 0;
}
You can put this in a main.cpp file, compile and run it. I tested it with the g++ compiler and it works fine.
The answer given by Valy is correct. But I would like remind you that C++ offers you another choice of declaring and defining methods, that is declaring method inside the class declaration and defining them outside the class declaration. This enables you to easily separate interface and implementation into .h and .cpp files, respectively, as shown below:
Point.h
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2);
void doubleX();
void doubleY();
int getX();
int getY();
};
Point.cpp
#include "Point.h"
Point::Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void Point::doubleX()
{
x *= 2;
}
void Point::doubleY()
{
y *= 2;
}
int Point::getX()
{
return x;
}
int Point::getY()
{
return y;
}
// PointTest.cpp
#include "Point.h"
int main()
{
// Do something with Point here
Point pt(1, 2);
std::cout << "Original: (" << pt.getX() << ", " << pt.getY() << ")" << std::endl;
pt.doubleX();
pt.doubleY();
std::cout << "After being doubled: (" << pt.getX() << ", " << pt.getY() << ")" << std::endl;
return 0;
}
And, how to compile:
g++ -o PointTest PointTest.cpp Point.cpp
Can't comment due to reputation but it seems vc++ outputs the error message you stated if you try to call
Point::doubleX
Here's a live example of the output:
http://rextester.com/ZLCEW66682
You should create an instance of the class and call the function using parens
In your second set of functions
void doubleX()
{
Point2::x = 2 * Point2::x;
};
void doubleY()
{
Point2::y = 2 * Point2::y;
};
If you want them to be member functions of the class Point, Point::y ... this is not how you should access the member data. Only static member variables can be accessed like that. The correct way is
void doubleX()
{
this->x = 2 * this->x;
};
void doubleY()
{
this->y = 2 * this->y;
};
That is using this pointer.

Why output of second program differs from first program?

When returning a reference to the object on which the function is invoked, the returned reference can be used to chain function calls on a single object.
Here, I am applying the same concept. But I am getting different output if I initialize objects differently.
First example:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1(5, 5);
// Chained function calls. All calls modify the same object
// as the same object is returned by reference
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Output is 10 and 20, which is correct.
However, output is not correct for the second example:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Output is 10 and 0.
Why? I think both are the same, the output of the second program should be 10 and 20 too. What is the reason it's different?
The difference is that the second version of your program returns by value. This means that the second call (i.e. setY) is performed on a copy of obj1, not on the obj1 itself. That's why only X ends up being set, but not Y.
In your first program, on the other hand, the setters return their results as a reference. This means that no copy is being made, so setY is called on the same object as setX, not on its copy.