C++ Operator Overloading in Class with Const Members? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
class SomeClass {
int someNum;
const int someConst;
public:
SomeClass() : someNum(12), someConst(15)
{
}
SomeClass operator+(int num) {
SomeClass newSomeClass;
newSomeClass.someNum += num;
return newSomeClass;
}
};
int main() {
SomeClass someClass;
SomeClass newClass;
newClass = someClass + 3;
}
I don't understand why the above doesn't compile, but does so when the const related code is removed.

The problem is here:
SomeClass newClass;
newClass = someClass + 3;
With the first instruction you create the object newClass and the member variable is initialized:
[...] someNum(12), someConst(15) [...]
With the second instruction you're trying to assign a new object constructed by the operator+ to the object.
So actually you're trying to modify the object itself which has a const variable member.
C++ provides a default assignment operator:
newClass = someClass + 3;
means "copy all variable mambers in the object on the right side of the = in the object in the left side".
In that case the variable someConst is declared as constant value, so you cannot overwrite its value. Indeed the operation make a compile error.
Solution
In order to handle this "problem" you need to write a custom assignment operator.
That's an example:
class SomeClass {
int someNum;
const int someConst;
public:
SomeClass() : someNum(12), someConst(15)
{
}
SomeClass operator+(int num) {
SomeClass newSomeClass;
newSomeClass.someNum += num;
return newSomeClass;
}
// Custom assignment operator
SomeClass& operator=(const SomeClass& oth) {
if (this != &oth) {
this->someNum = oth.someNum;
}
return *this;
}
};
In that way you're telling to copy from an object just the member variable someNum and to avoid the cost member.

Related

Will containing a `std::unique_ptr` make the default copy constructor a deleted function? [duplicate]

This question already has answers here:
Copy constructor for a class with unique_ptr
(6 answers)
Closed 4 years ago.
This code works fine:
class Test
{
int* ptr = new int(10);
};
int main()
{
Test o;
Test t = o;
}
But when we use unique_ptr instead raw ptr, we get an error:
error: use of deleted function 'Test::Test(const Test&)'
And sample code:
class Test
{
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = o;
}
What is going on?
What is going on?
You cannot create a second instance of Test because this implies you need a copy of the unique_ptr, which is not possbile. A unique_ptr can only be moved. Try implementing a move asignment operator and move o like so:
class Test
{
public:
Test() = default;
Test(Test&& other) noexcept
: ptr(std::move(other.ptr))
{
}
private:
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = std::move(o);
}
If you want to copy the int underlying the unique_ptr, you need to define a custom copy constructor like this:
class Test
{
public:
Test() = default;
Test(const Test& other)
:
ptr(new int(*other.ptr))
{
}
Test(Test&& other) noexcept
: ptr(std::move(other.ptr))
{
}
private:
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = o;
}
However, NOTE, that the pointers point to two DIFFERENT ints.
If you want shared ownership, you have to (and should) use shared_ptr like this:
class Test
{
private:
std::shared_ptr<int> ptr = std::make_shared<int>(1);
};
int main()
{
Test o;
Test t = o;
}
What is going on?
You've swapped from a naked pointer, to one that enforces ownership semantics. One that's smart.
This is literally the purpose of unique_ptr.
It enforces unique ownership.
You can't copy it; only move it.
If you really need Test to be copyable, and to be able to share ints, you're probably looking for shared_ptr.

Deleted copy constructor when member is an unique_ptr [duplicate]

This question already has answers here:
Copy constructor for a class with unique_ptr
(6 answers)
Closed 4 years ago.
This code works fine:
class Test
{
int* ptr = new int(10);
};
int main()
{
Test o;
Test t = o;
}
But when we use unique_ptr instead raw ptr, we get an error:
error: use of deleted function 'Test::Test(const Test&)'
And sample code:
class Test
{
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = o;
}
What is going on?
What is going on?
You cannot create a second instance of Test because this implies you need a copy of the unique_ptr, which is not possbile. A unique_ptr can only be moved. Try implementing a move asignment operator and move o like so:
class Test
{
public:
Test() = default;
Test(Test&& other) noexcept
: ptr(std::move(other.ptr))
{
}
private:
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = std::move(o);
}
If you want to copy the int underlying the unique_ptr, you need to define a custom copy constructor like this:
class Test
{
public:
Test() = default;
Test(const Test& other)
:
ptr(new int(*other.ptr))
{
}
Test(Test&& other) noexcept
: ptr(std::move(other.ptr))
{
}
private:
std::unique_ptr<int> ptr = std::make_unique<int>(1);
};
int main()
{
Test o;
Test t = o;
}
However, NOTE, that the pointers point to two DIFFERENT ints.
If you want shared ownership, you have to (and should) use shared_ptr like this:
class Test
{
private:
std::shared_ptr<int> ptr = std::make_shared<int>(1);
};
int main()
{
Test o;
Test t = o;
}
What is going on?
You've swapped from a naked pointer, to one that enforces ownership semantics. One that's smart.
This is literally the purpose of unique_ptr.
It enforces unique ownership.
You can't copy it; only move it.
If you really need Test to be copyable, and to be able to share ints, you're probably looking for shared_ptr.

C++ - Unable to overload assignment operator [duplicate]

This question already has answers here:
The assignment operator and initialization
(2 answers)
Closed 6 years ago.
I am trying to overload the assignment operator but it doesn't seem to work. The code is based on this answer. I've searched for other examples of overloading the assignment operator, but it doesn't seem like my code shouldn't run.
This is my code:
#pragma once
#include <assert.h>
class ReadOnlyInt
{
public:
ReadOnlyInt(): assigned(false) {}
ReadOnlyInt& operator=(int v);
operator int() const ;
private:
int value;
bool assigned;
};
ReadOnlyInt& ReadOnlyInt::operator=(int v)
{
assert(!assigned);
value = v;
assigned = true;
return *this;
}
ReadOnlyInt::operator int() const
{
assert(assigned);
return value;
}
Intellisense doesn't give any warnings, but the operator= is not highlighted as a keyword.
Now if I make an assigment, Intellisense does recognize it's not possible:
ReadOnlyInt bar = 12;
no suitable constructor exists to convert from "int" to "ReadOnlyInt"
This works however:
int foo = bar;
Solution
This question was marked as duplicate, so I can't answer it. This was the solution I came up with based on the comments and answer on this question:
ReadOnlyInt::ReadOnlyInt()
: assigned(false)
{}
ReadOnlyInt::ReadOnlyInt(int v)
: value(v), assigned(true)
{}
You can't initialize and declare at the same time. You need to do this
ReadOnlyInt bar;
bar = 12;
This is because there is no appropriate constructor for ReadOnlyInt that takes an int argument.

C++ Constructors Reasoning [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Why is the constructor H1 and H2 getting called? Can I get the reason?
class A
{
public:
int a;
char b;
A()
{
a = 0;
b = '\n';
}
A(int a)
{
cout << "H1";
}
A(char c)
{
cout << "H2";
}
};
int main()
{
int a = 10;
char c = 'h';
A ob1 = a;
ob1 = c;
}
A ob1 = a;
This initialises an object of type A from an int value. That uses the constructor A(int), printing H1.
ob1 = c;
This assigns a char value to the object. Since there isn't a suitable assignment operator A::operator=(char), which could assign the value directly, it does this in two stages:
Create a temporary object of type A from the char value
Assign that to ob1 using the implicit copy-assignment operator.
The first stage initialises the temporary using the constructor A(char), printing H2.
Hence, the output is H1H2.
class A {
public:
int a;
char b;
A() {
a=0;
b='\n';
}
A(int a) {
cout<<"H1";
}
A(char c) {
cout<<"H2";
}
};
int main() {
int a=10;
char c='h';
A ob1=a; // calls A(int a) because a is typeof int
ob1=c; // calls A(char c) because c is typeof char
}

c++ Cast MyClass* to int* [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I would like to cast a pointer to an instance of MyClass to an int*, preferably in such a way that I can do this:
void function(int*) {...};
MyClass * instance = new MyClass;
function(instance);
The int pointer should NOT be a binary copy of the MyClass pointer. Currently, I am using the following code to acheive a similar result:
int * MyClass::getIntPointer() {return &my_int;}
How do I cast a MyClass* to an int*?
Are you trying to access an int member of your class? If so, you can do this:
class MyClass {
public:
int myInt;
};
void function(int*) {...};
MyClass* instance = new MyClass;
function(&instance->myInt);
You don't want to cast MyClass to an int, you just want to access the member of MyClass.
So here's what that line means:
instance-> // follow the pointer to the actual MyClass object.
instance->myInt // access the int, "myInt"
&instance->myInt // get the address of that int
function(&instance->myInt); // call "function", passing to it the address of "myInt"
EDIT:
If you're creating a class that wraps an int, you can do this with a custom casting operator, as #cmbasnett suggests:
class MyClass {
public:
int* operator int*() { return &my_int; }
private:
int my_int;
};
MyClass instance;
function(instance); // this line will trigger the custom cast operator.
Maybe either of these strike your fancy:
#include <iostream>
struct MyClass
{
int myInt;
operator int*()
{
return &myInt;
}
};
int main()
{
MyClass* instance = new MyClass();
//method 1
instance->myInt = 42;
int* a = &(instance->myInt);
//method 2
int* b = *instance;
std::cout << *a << std::endl;
std::cout << *b << std::endl;
}
Sorry, you're stuck. You cannot overload the typecast operator for a pointer type. This is the only way you could cast from MyClass* directly to int* and require the resulting int* to point at the first int member, even if the class' storage is non-POD.
If you could guarantee that MyClass was always a POD type, then reinterpret_cast<int*>(instance) would be sufficient. But your demand that "The int pointer should NOT be a binary copy of the MyClass pointer" implies that there is no such guarantee.
If you were willing to start with a MyClass& instead of a MyClass*, then you could use cmbasnett's example of adding a typecast overload to the class.