Difference Visual and GDBonline answer? - c++

I have a problem, when i start a program in visual studio that i got this like an answer:
Token()
Operator+
Token(Token&&)
~Token(): 4
Operator=
~Token(): 4
But when i compiled , same source code in GDBonline i got this like an answer:
Token()
Operator+
Operator=
~Token(): 4
I want to ask you which answer is a good one?
#include <iostream>
using namespace std;
class Token{
public:
int a{1};
Token(){ //default constructor
cout << "Token()" << endl;
};
Token(int a0): a{a0} { //parametric constructor
cout << "Token(int)" << endl;
}
Token(const Token& t){ //copy constructor
this->a = t.a;
cout << "Token(const Token&)" << endl;
}
Token(Token&& t) noexcept{ //move constructor
this->a = t.a;
cout << "Token(Token&&)" << endl;
}
Token& operator=(const Token& t0){ //operator =
this->a = t0.a;
cout << "Operator=" << endl;
return *this;
}
Token operator+(const Token& t0){ //operator +
Token t;
t.a = this->a + t0.a;
cout << "Operator+" << endl;
return t;
//return Token{this->a + t0.a};
}
~Token(){ //destructor
cout << "~Token(): " << this->a << endl;
};
};
int main(){
Token t0;
Token t1{3};
Token t2;
t0 = t1 + t2;
return 0;
}

Related

why is this code not detecting << operator?

Please explain to me why this is not detecting the << operator.
I tried my best, even tried to overload << on both classes (which is not necessary).
#include<iostream>
using namespace std;
const int MAX = 10;
class Complex;
template<class t>
class stack {
private:
t stk[MAX];
int top;
public:
stack() { top = -1; }
void push(t data) {
if (top == MAX - 1)
cout << "Stack is full.";
else
stk[++top] = data;
}
t pop() {
if (top == -1) {
cout << "Stack is empty.";
return NULL;
}
else {
//return stk[top--];
t data = stk[top];
top--;
return data;
}
}
};
class Complex {
private:
float real, imag;
public:
Complex(float r = 0.0, float i = 0.0) { real = r; imag = i; }
friend ostream& operator << (ostream& s, Complex& c);
};
ostream& operator << (ostream& s, Complex& c) {
s << "(" << c.real << "," << c.imag << ")";
return s;
}
int main() {
stack<int> s1;
s1.push(10);
s1.push(20);
s1.push(30);
s1.push(40);
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
stack<float> s2;
s2.push(3.14f);
s2.push(4.14f);
s2.push(5.14f);
s2.push(6.14f);
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
Complex c1(1.5f, 2.5f), c2(1.5f, 2.5f), c3(1.5f, 2.5f), c4(1.5f, 2.5f);
//cout<<c1;
stack<Complex> s3;
s3.push(c1);
s3.push(c2);
s3.push(c3);
s3.push(c4);
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
return 0;
}
The function signature should be something like:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// write obj to stream
return os;
}
And the function pop can't return NULL since the type is not the same as t. Fixed code might like:
#include <iostream>
using namespace std;
const int MAX = 10;
class Complex;
template <class t>
class stack {
private:
t stk[MAX];
int top;
public:
stack() { top = -1; }
void push(t data) {
if (top == MAX - 1)
cout << "Stack is full.";
else
stk[++top] = data;
}
t pop() {
if (top == -1) {
cout << "Stack is empty.";
return {}; // May throw, or return std::optional here
} else {
// return stk[top--];
t data = stk[top];
top--;
return data;
}
}
};
class Complex {
private:
float real, imag;
public:
Complex(float r = 0.0, float i = 0.0) {
real = r;
imag = i;
}
friend ostream &operator<<(ostream &s, const Complex &c);
};
ostream &operator<<(ostream &s, const Complex &c) {
s << "(" << c.real << "," << c.imag << ")";
return s;
}
int main() {
stack<int> s1;
s1.push(10);
s1.push(20);
s1.push(30);
s1.push(40);
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
stack<float> s2;
s2.push(3.14f);
s2.push(4.14f);
s2.push(5.14f);
s2.push(6.14f);
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
Complex c1(1.5f, 2.5f), c2(1.5f, 2.5f), c3(1.5f, 2.5f), c4(1.5f, 2.5f);
// cout<<c1;
stack<Complex> s3;
s3.push(c1);
s3.push(c2);
s3.push(c3);
s3.push(c4);
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
return 0;
}
Online demo.
Related question: What are the basic rules and idioms for operator overloading?
It doesn't work because the second parameter should be a const reference
class Complex{
private:
float real,imag;
public:
Complex(float r=0.0,float i=0.0){
real=r;
imag=i;
}
friend ostream& operator<<(ostream& s, const Complex& c);
};
ostream& operator<<(ostream& s, const Complex& c) {
s<<"("<<c.real<<","<<c.imag<<")";
return s;
}
Reason:
The pop function returns an r-value. You can think of an r-value as a nameless object in memory (of course, there is more to it). You cannot put an r-value into an l-value reference. But for a const reference, it does not matter, since you are not going to modify it.
Solution 1:
friend ostream &operator<<(ostream &s, Complex &c); // accepts lvalue - c refers to some external Complex object.
friend ostream &operator<<(ostream &s, Complex &&c); // accepts rvalue - c becomes a normal local variable whose value is the passed rvalue.
Solution 2:
friend ostream &operator<<(ostream &s, const Complex &c); // accepts both

how to overload assignment operator to satisfy ob1=ob2=ob3 (ob1,ob2,ob3 are objects of same class)

how to overload assignment operator to satisfy ob1=ob2=ob3 (ob1,ob2,ob3 are objects of same class) where we have no concern for (ob2 = ob3) which is similar to (ob2.operator=(ob3)) but we need a parameter of type class when we are assigning this result to ob1 which is similar to (ob1.operator=(ob2.operator=(ob3)) below is the code that gives me error
#include<bits/stdc++.h>
using namespace std;
class A
{
public:
int x;
int *ptr;
A()
{
}
A(int a, int *f)
{
x = a;
ptr = f;
}
void operator=(A&);
};
void A::operator=(A &ob)
{
this->x = ob.x;
*(this->ptr) = *(ob.ptr);
}
int main()
{
int *y = new int(3);
A ob1, ob2, ob3(5, y);
ob1 = ob2 = ob3;
cout << ob1.x << " " << *(ob1.ptr) << endl;
cout << ob2.x << " " << *(ob2.ptr) << endl;
cout << ob3.x << " " << *(ob3.ptr) << endl;
return 0;
}
Your asignement operator should return a reference to *this, and be defined as
A& operator=(const A&);
or, better, pass by value and use the copy-and-swap idiom
A& operator=(A);
For an excellent intro to operator overloading, see this.

How to overload + operator in a heap allocated var

class a{
int *var = new int;
public:
//constructor and destructor
a(int a):var(new int(5)){}
~a() {delete var;}
int get() const {return *var}
//overload of + oporator
a operator+(const a & rhs){return a(*var+rhs.get()
//overload of ++ operator
a a::operator++ (int)
}
a a::operator+ (const a & rhs) {
return a(*itsRadius + rhs.get());
}
a a::operator++ (int){
a temp(*this);
*itsRadius= *itsRadius+1;
return temp;}
}
now when i do like this:
a c(10),d,g;
g=c+d;
i get g = to some address instead of 15 .
why is that?
and when i fo c++ i get an error (in the distructor when he try to delete),why is that?
Here is a working example. You need also to read about the rule of three:
#include <iostream>
class Int
{
int *_value;
public:
Int(int value) : _value(new int(value))
{
}
~Int()
{
delete _value;
}
Int(Int const &rhs) : _value(new int(*rhs._value))
{
}
Int & operator=(Int const &rhs)
{
*_value = *rhs._value;
return *this;
}
Int operator+(Int &rhs) const
{
return Int(*rhs._value + *_value);
}
operator int() const
{
return *_value;
}
};
int main(void)
{
Int a(10),
b(32),
c(a + b);
std::cout << c << "\n";
a = c;
std::cout << a << "\n";
}
And also, it is a bad idea to use raw C pointers in C++. Read about the std::unique_ptr.
o.k. so i solve the problem , this is the working code :
class SimpleCircle {
int *itsRadius;
public:
SimpleCircle():itsRadius(new int(5)) { cout << "constructor initialized" << endl;}
SimpleCircle(int num) { itsRadius = new int(num); cout << "constructor" << endl;}
SimpleCircle(const SimpleCircle &rhs) : itsRadius(new int(*rhs.itsRadius)){ cout << "copy constructor" << endl; }
~SimpleCircle(){ delete itsRadius; cout << "destructor" << endl;}
//perfect
int get() const {return *itsRadius;}
void set(int num) { *itsRadius = num;}
//-------
//plus operator
SimpleCircle operator+(const SimpleCircle &);
//inc operator
SimpleCircle operator++();
SimpleCircle operator++(int);
//= operator
SimpleCircle & operator=(const SimpleCircle &);
};
SimpleCircle SimpleCircle::operator+ (const SimpleCircle & rhs) {
return SimpleCircle(*itsRadius + *rhs.itsRadius);
}
SimpleCircle SimpleCircle::operator++() {
int a = *itsRadius;
++a;
*itsRadius=a;
return *this;
}
SimpleCircle SimpleCircle::operator++ (int){
SimpleCircle temp(*this);
*itsRadius= *itsRadius+1;
return temp;
}
SimpleCircle & SimpleCircle::operator= (const SimpleCircle & rhs) {
if (this == &rhs)
return *this;
*itsRadius = *rhs.itsRadius;
return *this;
}
int main()
{
SimpleCircle a;
cout << a.get() << endl;
SimpleCircle b(15);
cout << b.get() << endl;
SimpleCircle c = a + b;
cout << "a: "<< a.get() << endl;
cout << "b: " << b.get() << endl;
cout << "c: " << c.get() << endl;
a++;
cout << "a: " << a.get() << endl;
++a;
cout << "a: " << a.get() << endl;
now the reason in the former code i had 2 problem (that was 1 becoase of the outher)
1 c was equal to some garbege instead of a number
2 the program break in the end destructor
the reason was i forgat o add a operator= , so it didn't know how to treat to :
c=a+b;
after i fixed it , all come together nicely

C++ Cycle through the addresses of an object

Objects (that are not dynamic) are blocks of data in memory.
Is there a way to cycle through and print each item in an object?
I tried doing it with 'this' but I keep getting errors.
#include "stdafx.h"
#include <iostream>
#include "TestProject.h"
using namespace std;
class myclass {
int someint = 10;
double somedouble = 80000;
int somearray[5] = {0, 1, 2, 3, 4};
public:
void somefunction();
};
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1;
cout << "\n test2 \n" << *somepointer;
//Error: no opperator '<<' matches these operands
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
I'm guessing the error is because the types don't match. But I can't really figure a solution. Is there a dynamic type, or do I have to test the type somehow?
You must add friend global std::ostream operator << to display content of object
#include "stdafx.h"
#include <iostream>
using namespace std;
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1; // wrong pointer to object with `object + sizeof(object)` address,
// data probably has been corrupted
cout << "\n test2 \n" << *somepointer; // displaying objects content
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
as you want to get to the object member using its pointers shifts I post another program
#include "stdafx.h"
#include <iostream>
using namespace std;
#pragma pack (push, 1) // force data alignment to 1 byte
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
#pragma pack (pop) // restore data alignment
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
int* pSomeInt = (int*)this; // get someint address
double *pSomeDouble = (double*)(pSomeInt + 1); // get somedouble address
int* pSomeArray = (int*)(pSomeDouble + 1); // get somearray address
std::cout << "someint: " << *pSomeInt << std::endl
<< "somedouble: " << *pSomeDouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
std::cout << pSomeArray[iIndex] << " }" << std::endl;
else
std::cout << pSomeArray[iIndex] << ", ";
}
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
C++, by design, has no reflection feature. This means there is no generic, type-independent way to acces type metadata (e.g. the list of members if a class and their types) at runtime. So what you're trying to do (if I understand it correctly) cannot be done in C++.
Also I'm not sure what you meant by "objects (that are not dynamic)". all objects are blocks of data in memory, regardless of whether they are dynamically allocated or not.

Passing by value doesn't invoke move constructor

I have the following small class:
/// RAII wrapper for a Lua reference
class reference
{
public:
/// Construct empty reference
reference() : m_L(NULL), m_ref(LUA_NOREF) {}
/// Construct reference from Lua stack
reference(lua_State* L, int i = -1) : m_L(L) {
lua_pushvalue(L, i);
m_ref = luaL_ref(L, LUA_REGISTRYINDEX);
}
/// Destructor
~reference() {
if (m_L) luaL_unref(m_L, LUA_REGISTRYINDEX, m_ref);
}
/// Copy constructor
reference(const reference& r) : m_L(r.m_L) {
r.push();
m_ref = luaL_ref(m_L, LUA_REGISTRYINDEX);
}
/// Move constructor
reference(reference&& r) : m_L(r.m_L), m_ref(r.m_ref) {
r.m_L = NULL; // make sure r's destructor is NOP
}
/// Assignment operator
reference& operator=(reference r) {
swap(r, *this);
return *this;
}
/// Swap with other reference
friend void swap(reference& a, reference& b)
{
std::swap(a.m_L, b.m_L);
std::swap(a.m_ref, b.m_ref);
}
void push() const { lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_ref); }
private:
lua_State* m_L;
int m_ref;
};
Note that the assignment operator is implemented using the copy-and-swap idiom and is supposed to call the move constructor, if used with an rvalue.
However, reference r; r = reference(L); calls the copy constructor before entering the assignment operator. Why, oh why?
Writing two assignment operators helps:
/// Assignment operator
reference& operator=(const reference& r) {
reference copy(r);
swap(copy, *this);
return *this;
}
/// Move assignment operator
reference& operator=(reference&& r) {
swap(r, *this);
return *this;
}
However, at the cost of disabling copy elision.
Isn't pass-by-value supposed to work here as expected? Or is even my compiler (Clang on Mac) broken?
Update:
The following small test-case works correctly:
#include <iostream>
using namespace std;
struct resource
{
resource(int i=1) : i(i) { print(); }
~resource() { print(); i = 0; }
void print() const
{
cout << hex << " " << uint16_t(uintptr_t(this)) << ") " << dec;
}
int i;
};
resource* alloc_res()
{
cout << " (alloc_res";
return new resource(0);
}
resource* copy_res(resource* r)
{
cout << " (copy_res";
return new resource(r->i);
}
void free_res(resource* r)
{
if (r) cout << " (free_res";
delete r;
}
struct Test
{
void print() const
{
cout << hex << " [&=" << uint16_t(uintptr_t(this))
<< ", r=" << uint16_t(uintptr_t(r)) << "] " << dec;
}
explicit Test(int j = 0) : r(j ? alloc_res() : NULL) {
cout << "constructor"; print();
cout << endl;
}
Test(Test&& t) : r(t.r) {
cout << "move"; print(); cout << "from"; t.print();
t.r = nullptr;
cout << endl;
}
Test(const Test& t) : r(t.r ? copy_res(t.r) : nullptr) {
cout << "copy"; print(); cout << "from"; t.print();
cout << endl;
}
Test& operator=(Test t) {
cout << "assignment"; print(); cout << "from"; t.print(); cout << " ";
swap(t);
return *this;
cout << endl;
}
void swap(Test& t)
{
cout << "swapping"; print();
cout << "and"; t.print();
std::swap(r, t.r);
cout << endl;
}
~Test()
{
cout << "destructor"; print();
free_res(r);
cout << endl;
}
resource* r;
};
int main()
{
Test t;
t = Test(5);
}
If compiled with clang++ --std=c++11 -O0 -fno-elide-constructors test.cpp -o test the move constructor is called. (Thanks for the switch, Benjamin Lindley)
The question is now: why does it work now? What's the difference?
There is no legal C++11 circumstance that would cause the calling of a copy constructor in r = reference(L);.
This is effectively equivalent to r.operator =(reference(L));. Since operator= takes its parameter by value, one of two things will happen.
The temporary will be used to construct the value. Since it's a temporary, it will preferentially call reference's move constructor, thus causing a move.
The temporary will be elided directly into the value argument. No copying or moving.
After this, operator= will be called, which doesn't do any copying internally.
So this looks like a compiler bug.