How to override an operator for polymorphism












7















Can anyone explain to me what I'm doing wrong here?



struct X {
int x{};

explicit X(int x) : x(x) {}

virtual X &operator++() = 0;
};

struct OK : X {
int ok{};

explicit OK(int ok) : X(ok), ok(ok) {}

X &operator++() override {
ok += 10;
return *this;
}
};

struct MU : X {
int mu{};

explicit MU(int mu) : X(mu), mu(mu) {}

X &operator++() override {
mu *= 5;
return *this;
}
};

int main() {
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};


All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:






Base* base = new Derivate();



++base <--- the ++ should be called from the Derivate class







Base* base2 = ned Derivate_2();



++base <--- the ++ should be called from the Derivate_2 class






UPDATE:



The current solution to my problem is to use ++(*base) which I know about this already.



But is there any other way to do ++base instead of ++(*base)?





Thanks for the help :)










share|improve this question




















  • 2





    x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

    – Peter
    10 hours ago











  • To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

    – Öö Tiib
    10 hours ago











  • Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

    – john
    9 hours ago
















7















Can anyone explain to me what I'm doing wrong here?



struct X {
int x{};

explicit X(int x) : x(x) {}

virtual X &operator++() = 0;
};

struct OK : X {
int ok{};

explicit OK(int ok) : X(ok), ok(ok) {}

X &operator++() override {
ok += 10;
return *this;
}
};

struct MU : X {
int mu{};

explicit MU(int mu) : X(mu), mu(mu) {}

X &operator++() override {
mu *= 5;
return *this;
}
};

int main() {
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};


All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:






Base* base = new Derivate();



++base <--- the ++ should be called from the Derivate class







Base* base2 = ned Derivate_2();



++base <--- the ++ should be called from the Derivate_2 class






UPDATE:



The current solution to my problem is to use ++(*base) which I know about this already.



But is there any other way to do ++base instead of ++(*base)?





Thanks for the help :)










share|improve this question




















  • 2





    x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

    – Peter
    10 hours ago











  • To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

    – Öö Tiib
    10 hours ago











  • Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

    – john
    9 hours ago














7












7








7








Can anyone explain to me what I'm doing wrong here?



struct X {
int x{};

explicit X(int x) : x(x) {}

virtual X &operator++() = 0;
};

struct OK : X {
int ok{};

explicit OK(int ok) : X(ok), ok(ok) {}

X &operator++() override {
ok += 10;
return *this;
}
};

struct MU : X {
int mu{};

explicit MU(int mu) : X(mu), mu(mu) {}

X &operator++() override {
mu *= 5;
return *this;
}
};

int main() {
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};


All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:






Base* base = new Derivate();



++base <--- the ++ should be called from the Derivate class







Base* base2 = ned Derivate_2();



++base <--- the ++ should be called from the Derivate_2 class






UPDATE:



The current solution to my problem is to use ++(*base) which I know about this already.



But is there any other way to do ++base instead of ++(*base)?





Thanks for the help :)










share|improve this question
















Can anyone explain to me what I'm doing wrong here?



struct X {
int x{};

explicit X(int x) : x(x) {}

virtual X &operator++() = 0;
};

struct OK : X {
int ok{};

explicit OK(int ok) : X(ok), ok(ok) {}

X &operator++() override {
ok += 10;
return *this;
}
};

struct MU : X {
int mu{};

explicit MU(int mu) : X(mu), mu(mu) {}

X &operator++() override {
mu *= 5;
return *this;
}
};

int main() {
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};


All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:






Base* base = new Derivate();



++base <--- the ++ should be called from the Derivate class







Base* base2 = ned Derivate_2();



++base <--- the ++ should be called from the Derivate_2 class






UPDATE:



The current solution to my problem is to use ++(*base) which I know about this already.



But is there any other way to do ++base instead of ++(*base)?





Thanks for the help :)







c++ polymorphism operator-overloading operators






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 10 hours ago







Vali

















asked 10 hours ago









ValiVali

1068




1068








  • 2





    x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

    – Peter
    10 hours ago











  • To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

    – Öö Tiib
    10 hours ago











  • Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

    – john
    9 hours ago














  • 2





    x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

    – Peter
    10 hours ago











  • To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

    – Öö Tiib
    10 hours ago











  • Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

    – john
    9 hours ago








2




2





x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

– Peter
10 hours ago





x_base is a pointer to X. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x has undefined behaviour, since, after incrementing, x_base doesn't point at an object that exists. Change the incrementing to ++(*x_base).

– Peter
10 hours ago













To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

– Öö Tiib
10 hours ago





To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.

– Öö Tiib
10 hours ago













Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

– john
9 hours ago





Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.

– john
9 hours ago












2 Answers
2






active

oldest

votes


















9














In these two lines,



X *x_base = new OK(0);
++x_base;


you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:



++*x_base; // or ++(*x_base), might be more readable


You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.



OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it


Note that the implementation of the operator overload that is called doesn't change the value of X::x. The std::cout << x_base->x; after the increment suggests that you expect the value to be non-zero.






share|improve this answer


























  • and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

    – Vali
    10 hours ago






  • 2





    @Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

    – David K
    7 hours ago





















2














To solve your second question you need to write a wrapper for your pointer class. Something like



class XPtr
{
public:
XPtr(X* p) : ptr(p) {}
X* operator->() { return ptr; }
X& operator*() { return *ptr; }
XPtr& operator++() { ++*ptr; return *this; }
private:
X* ptr;
};

int main() {
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};





share|improve this answer



















  • 1





    This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

    – David K
    7 hours ago











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54746008%2fhow-to-override-an-operator-for-polymorphism%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









9














In these two lines,



X *x_base = new OK(0);
++x_base;


you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:



++*x_base; // or ++(*x_base), might be more readable


You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.



OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it


Note that the implementation of the operator overload that is called doesn't change the value of X::x. The std::cout << x_base->x; after the increment suggests that you expect the value to be non-zero.






share|improve this answer


























  • and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

    – Vali
    10 hours ago






  • 2





    @Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

    – David K
    7 hours ago


















9














In these two lines,



X *x_base = new OK(0);
++x_base;


you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:



++*x_base; // or ++(*x_base), might be more readable


You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.



OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it


Note that the implementation of the operator overload that is called doesn't change the value of X::x. The std::cout << x_base->x; after the increment suggests that you expect the value to be non-zero.






share|improve this answer


























  • and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

    – Vali
    10 hours ago






  • 2





    @Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

    – David K
    7 hours ago
















9












9








9







In these two lines,



X *x_base = new OK(0);
++x_base;


you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:



++*x_base; // or ++(*x_base), might be more readable


You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.



OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it


Note that the implementation of the operator overload that is called doesn't change the value of X::x. The std::cout << x_base->x; after the increment suggests that you expect the value to be non-zero.






share|improve this answer















In these two lines,



X *x_base = new OK(0);
++x_base;


you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:



++*x_base; // or ++(*x_base), might be more readable


You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.



OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it


Note that the implementation of the operator overload that is called doesn't change the value of X::x. The std::cout << x_base->x; after the increment suggests that you expect the value to be non-zero.







share|improve this answer














share|improve this answer



share|improve this answer








edited 10 hours ago

























answered 10 hours ago









lubgrlubgr

12.2k21846




12.2k21846













  • and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

    – Vali
    10 hours ago






  • 2





    @Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

    – David K
    7 hours ago





















  • and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

    – Vali
    10 hours ago






  • 2





    @Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

    – David K
    7 hours ago



















and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

– Vali
10 hours ago





and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.

– Vali
10 hours ago




2




2





@Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

– David K
7 hours ago







@Vali I think this answer shows that you can solve your problem by making the variable x have type X& rather than X*. Then ++x will act on the object rather than on a pointer. Frankly I think this is better than the other answer.

– David K
7 hours ago















2














To solve your second question you need to write a wrapper for your pointer class. Something like



class XPtr
{
public:
XPtr(X* p) : ptr(p) {}
X* operator->() { return ptr; }
X& operator*() { return *ptr; }
XPtr& operator++() { ++*ptr; return *this; }
private:
X* ptr;
};

int main() {
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};





share|improve this answer



















  • 1





    This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

    – David K
    7 hours ago
















2














To solve your second question you need to write a wrapper for your pointer class. Something like



class XPtr
{
public:
XPtr(X* p) : ptr(p) {}
X* operator->() { return ptr; }
X& operator*() { return *ptr; }
XPtr& operator++() { ++*ptr; return *this; }
private:
X* ptr;
};

int main() {
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};





share|improve this answer



















  • 1





    This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

    – David K
    7 hours ago














2












2








2







To solve your second question you need to write a wrapper for your pointer class. Something like



class XPtr
{
public:
XPtr(X* p) : ptr(p) {}
X* operator->() { return ptr; }
X& operator*() { return *ptr; }
XPtr& operator++() { ++*ptr; return *this; }
private:
X* ptr;
};

int main() {
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};





share|improve this answer













To solve your second question you need to write a wrapper for your pointer class. Something like



class XPtr
{
public:
XPtr(X* p) : ptr(p) {}
X* operator->() { return ptr; }
X& operator*() { return *ptr; }
XPtr& operator++() { ++*ptr; return *this; }
private:
X* ptr;
};

int main() {
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
};






share|improve this answer












share|improve this answer



share|improve this answer










answered 9 hours ago









johnjohn

36.6k12847




36.6k12847








  • 1





    This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

    – David K
    7 hours ago














  • 1





    This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

    – David K
    7 hours ago








1




1





This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

– David K
7 hours ago





This has the very unpleasant effect of making something that acts like a pointer except when you apply ++ to it. It seems to me this violates the principle of least surprise.

– David K
7 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54746008%2fhow-to-override-an-operator-for-polymorphism%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Fluorita

Hulsita

Península de Txukotka