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