suppose I have those 2 classes:
class num{
public:
int a;
num(){};
num(int x):a(x){};
num(const num& n):a(n.a){}
virtual bool operator==(const num& n)const = 0;
virtual ~num(){};
};
class tmp: public num{
public:
tmp(){};
tmp(int x):num(x){};
tmp(const num& n): num(n){}
tmp(const tmp& t): num(t.a){}
virtual bool operator==(const num& n)const{
return tmp(n).a == a;
}
virtual ~tmp(){};
};
and something like this in main:
int main() {
num* x = &get(...);
return 0;
}
get return a reference of type tmp (in this case. in general it returns reference to a type that inherits from num)
what I want to do is create another num* y that will point to a copy of *x so that if I change *y I won't change *x. and I can't quite figure out how to do this since num is abstract so I can't create an object of this type to make a copy.
ok and another question.
if I overload << operator:
std::ostream& operator<<(std::ostream& os, const tmp& t){
return os<<t.a<<endl;
}
and then try to do this:
cout<<*x<<endl;
I get an error no match for 'operator<<'
why is that?
You're looking for the prototype pattern, also often called clone pattern.
It's basically a pure virtual method
virtual std::unique_ptr<num> clone() const = 0;
... that you declare in num, to be overriden by each derived class. You then just call x->clone(); to get a brand new object of the correct type.
You'll need a virtual function to clone an object based on its dynamic type. It will have to return a (preferably smart) pointer to a newly allocated object of the correct type. For example:
class num {
public:
virtual std::unique_ptr<num> clone() const = 0;
// other members...
};
class my_num : public num {
public:
virtual std::unique_ptr<num> clone() const {
return std::make_unique<my_num>(*this);
}
// other members...
};
int main() {
num* x = &get(...);
auto y = x->clone();
}
Related
I aim to implement an operator on derived classes such that the return type should be of the derived class.
I was able to achieve it with the following code:
#include <iostream>
class Base{
public:
virtual Base&& operator+ (const Base &b) = 0;
virtual void Val() = 0;
};
class Derived : public Base{
public:
Derived&& operator+ (const Base &b) override
{
Derived *res = new Derived;
auto tmp = dynamic_cast<const Derived*>(&b);
if(tmp) res->fVal = this->fVal+tmp->fVal;
return std::move(*res);
}
void SetVal(double val){fVal = val;}
void Val() override{std::cout<<"derived:"<<fVal<<std::endl;}
private:
double fVal{0};
};
int main(){
Derived a;
a.SetVal(2);
Derived b;
b.SetVal(3);
Base *baseptr = new Derived(a+b);
baseptr->Val();
Base &&d = a+b;
d.Val();
Derived e = dynamic_cast<Derived&>(d);
e.Val();
return 0;
}
I am not really confortable with using an rvalue-reference for the return type, so I would like to know if there is a simpler solution that I cannot see. Returning a copy of the derived type didn't work, as gcc states that the return type is not covariant.
EDIT: As #ofo has mentioned, I could achieve something quite similar returning a lvalue-reference. For now it is the option that suits me the best. However, it is still undesirable (to say the least) that there is a memory leak waiting to happen, I just need to not do anything with the result of a+b;
I don't see a way of achieving this without returning a pointer, as suggested by #Eljay. Returning a reference could work but I see no way of ensuring that the caller will delete whatever needs to be deleted.
I thought of this (where func represents a scenario in which I would use the operator):
#include <iostream>
#include <memory>
class Base{
public:
virtual std::unique_ptr<Base> operator+(const Base &) = 0;
virtual void SetVal(double) = 0;
virtual void Val() = 0;
};
class Derived : public Base{
public:
std::unique_ptr<Base> operator+(const Base &b) override
{
std::unique_ptr<Base> res = std::make_unique<Derived>();
auto tmp = dynamic_cast<const Derived*>(&b);
if(tmp) res->SetVal(this->fVal+tmp->fVal);
else std::cout<<"now i deal with invalid type case"<<std::endl;
return res;
}
void SetVal(double val) override{fVal = val;}
void Val(){std::cout<<fVal<<std::endl;}
private:
double fVal{0};
};
void func(Base &a, Base &b)
{
auto res = a+b;
res->Val();
}
int main(){
Derived a;
a.SetVal(2);
Derived b;
b.SetVal(3);
auto d = a+b;
d->Val();
func(a,b);
return 0;
}
I will leave this up for a while in case someone finds a better solution. Otherwise I will mark it as an answer.
This is a C++(11) question.
I have a object Obj myObj encapsulating an object f of type MyType.
Depending on runtime context, the object fshould behave differently.
One natural way of implementing this would be for the class Obj to encapsulate a pointer to an abstract base class MyType, which would, depending on the context point to different (public) child of MyType, such as MyType1, MyType2, etc.
However, I'm not very keen on Obj "suffering" the consequences of MyType being polymorphic, i.e. having to deal with a pointer. In particular, if I make it a std::unique_ptr<MyType>, it implies that Obj can either not be copied or that one needs to give it a proper copy constructor that deals with copying MyType ressources.
In my opinion, MyType being polymorphic shouldn't be Obj's problem.
I came with the following classes. Essentially the idea is to hide the pointer within MyTypeprivate attributes. In addition my second question concerns the fact that concrete implementations of MyTypeImpl may share some code shouldn't be repeated. I've put that in a class from which concrete implementations privately inherit.
I'm curious what more expert developers than me would think about it. Is it too heavy "just to hide the pointer"? Is there a better way to do it?
#include <iostream>
#include <memory>
// a "standard" implementation of MyType
class MyTypeImpl
{
public:
virtual double operator()(double a) = 0;
virtual int implType() const = 0;
virtual void complexStuff() const = 0;
};
// some internal stuff common to all implementations
class MyTypeImplInternals
{
protected:
MyTypeImplInternals(int value):factor_{value}{}
int factor_;
void longCommonFunction() const{ std::cout << "I'm doing complex stuff common to all interfaces " << factor_ << "\n" ;}
};
// one specific implementation
class MyTypeImpl1: public MyTypeImpl, private MyTypeImplInternals
{
public:
MyTypeImpl1(int factor):MyTypeImplInternals{factor}{};
virtual double operator()(double a) override {return factor_*a;}
virtual int implType() const override {return 1;}
virtual void complexStuff() const override { longCommonFunction(); }
};
// a second implementation
class MyTypeImpl2: public MyTypeImpl, private MyTypeImplInternals
{
public:
MyTypeImpl2(int factor):MyTypeImplInternals{factor}{};
virtual double operator()(double a) override {return factor_*a;}
virtual int implType() const override {return 2;}
virtual void complexStuff() const override { longCommonFunction(); }
};
class MyTypeImplFactory
{
public:
static std::unique_ptr<MyTypeImpl>createMyTypeImpl(int implementationType)
{
switch(implementationType)
{
case 1:
return std::unique_ptr<MyTypeImpl> (new MyTypeImpl1(12));
case 2:
return std::unique_ptr<MyTypeImpl> (new MyTypeImpl2(22));
default:
throw std::runtime_error("implementation does not exist...\n");
return nullptr;
}
}
};
// my type
class MyType
{
public:
MyType(int implementationType)
{
implPtr_ = MyTypeImplFactory::createMyTypeImpl(implementationType);
}
MyType(MyType const& source)
: implPtr_{ MyTypeImplFactory::createMyTypeImpl(source.implType()) }
{
}
double operator()(double a){return (*implPtr_)(a);}
int implType() const {return implPtr_->implType();}
void complexStuff() const {implPtr_->complexStuff();}
private:
std::unique_ptr<MyTypeImpl> implPtr_;
};
class Obj
{
private:
MyType f;
public:
Obj(int dim):f{dim}{}
Obj(Obj&& sourceToMove) = default;
Obj(Obj const& source) = default;
void doStuff() {std::cout << "I'm doing stuff() " << f(2) << std::endl; f.complexStuff();}
};
int main()
{
Obj myObj{1}, myObj2{2};
myObj.doStuff();
myObj2.doStuff();
Obj myObj3{std::move(myObj2)}; // myObj2 now dead
Obj myObj4{myObj};
myObj3.doStuff();
myObj4.doStuff();
}
link to online compiler : http://cpp.sh/8rhyy
Here the implementations are very dumb ones to serve as an example. An application for this design could be for instance a Solver (Obj) that solves some kind of physics Equation (MyType) which exact definition depends on the dimensionality of the problem, equation in 1D space is not the same as in 2D or in 3D. Solver's code would be completely independent on Equation's dimensionality and also wouldn't have to deal with a pointer. Equation would hide its 1D, 2D, or 3D implementation from outside's world.
(was originally a post on code review that was put on Hold because to abstract)
This proposed class design appears to have an obvious problem. The polymorphic type is referenced by a std::unique_ptr:
std::unique_ptr<MyTypeImpl> implPtr_;
Obj's default copy constructor, and assignment operator will end up transferring the held pointer to the new object, leaving the std::unique_ptr in the original object staring at a nullptr. Not good.
At the bare minimum this should be either a std::shared_ptr, or Obj's copy constructor and assignment operator will need to instantiate a new implPtr_. Note that with the easy std::shared_ptr fix the result of the copy constructor and an assignment operator is having multiple instances of Obj referencing the same instance of MyTypeImpl, which may or may not be an issue.
A much simpler class design is simply have MyTypeImpl1 and MyTypeImpl2 be subclasses of Obj, implementing the required polymorphic behavior.
I just refactored your codes.
#include <iostream>
#include <memory>
// !abstraction
class MyType
{
public:
virtual double operator()(double a) = 0;
virtual int implType() const = 0;
virtual void complexStuff() const = 0;
};
// !!MyTypeImplInternals could be a super class of MyTypeImpl* if it has properties(such as factor_) or just some static functions.
class MyTypeImplInternals
{
public:
MyTypeImplInternals(int value):factor_{value}{}
int factor_;
void longCommonFunction() const{ std::cout << "I'm doing complex stuff common to all interfaces " << factor_ << "\n" ;}
};
// one specific implementation
class MyTypeImpl1: public MyType
{
MyTypeImplInternals internal_;
public:
MyTypeImpl1(int factor):internal_{factor}{};
virtual double operator()(double a) override {return internal_.factor_*a;}
virtual int implType() const override {return 1;}
virtual void complexStuff() const override { internal_.longCommonFunction(); }
};
// a second implementation
class MyTypeImpl2: public MyType
{
MyTypeImplInternals internal_;
public:
MyTypeImpl2(int factor):internal_{factor}{};
virtual double operator()(double a) override {return internal_.factor_*a;}
virtual int implType() const override {return 2;}
virtual void complexStuff() const override { internal_.longCommonFunction(); }
};
std::unique_ptr<MyType> createMyType(int implementationType)
{
switch(implementationType)
{
case 1:
return std::unique_ptr<MyType> (new MyTypeImpl1(12));
case 2:
return std::unique_ptr<MyType> (new MyTypeImpl2(22));
default:
throw std::runtime_error("implementation does not exist...\n");
return nullptr;
}
}
class Obj
{
private:
std::unique_ptr<MyType> f_;
public:
Obj(int dim):f_(createMyType(dim)){}
Obj(Obj&& sourceToMove) : f_(std::move(sourceToMove.f_)) {}
Obj(Obj const& source) : f_(createMyType(source.f_->implType())) {}
void doStuff() {std::cout << "I'm doing stuff() " << (*f_)(2) << std::endl; f_->complexStuff();}
};
int main()
{
Obj myObj{1}, myObj2{2};
myObj.doStuff();
myObj2.doStuff();
Obj myObj3{std::move(myObj2)}; // myObj2 now dead
Obj myObj4{myObj}; //!!Bad idea to share an implementation to more Objs.
myObj3.doStuff();
myObj4.doStuff();
}
Let's say I'm trying to define an abstract base class for "mathematical functions" - i.e. things that look like y=f(x) where both x and y are numeric types, and x is in the "domain" of f. Here's what my abstract base class might look like:
template<typename T>
class AbstractFunction{
public:
virtual bool CheckDomain(T) const = 0;
virtual T operator()(T) const = 0;
};
This says that any concrete class derived from AbstractFunction must implement a CheckDomain method and an "evaluation operator" (). Now what I'd like to do is require that the evaluation operator calls the CheckDomain function before evaluating the function. Is there a neat way to do some sort of "partial implementation" for operator()(T)? Obviously this would mean it's no longer a pure virtual.
I thought I had it figured out with the following construction, but I must be missing something because if I create ConcreteFunction f and try to evaluate f(1.0), it doesn't use the derived class methods (it always returns 0 for CheckDomain(x)).
class AbstractFunction{
public:
virtual bool CheckDomain(double) const = 0;
virtual double EvalFunction(double) const = 0;
virtual double operator()(double);
};
double AbstractFunction::operator()(double x){
bool D = CheckDomain(x);
if(D==1){
return EvalFunction(x);
}
else{
std::runtime_error("Error: Out of Domain");
}
}
class ConcreteFunction : public AbstractFunction{
public:
bool CheckDomain(double x) const {(x>0.0)? 1:0;}
double EvalFunction(double x) const {return x*x;}
// Don't need to define operator(), should inherit from AbstractFunction.
};
I'm sure I'm missing something easy, any thoughts?
Actually, my method works! I just spaced out on my definition of ConcreteFunction::CheckDomain. I did the domain check, but didn't return it! The following code compiles and runs as desired:
#include<stdexcept>
#include<iostream>
class AbstractFunction{
public:
virtual bool CheckDomain(double) const = 0;
virtual double EvalFunction(double) const = 0;
virtual double operator()(double) const;
};
double AbstractFunction::operator()(double x) const{
bool D = CheckDomain(x);
if(D==1){
return EvalFunction(x);
}
else{
throw std::runtime_error("Error: Out of Domain");
}
}
class ConcreteFunction : public AbstractFunction{
public:
bool CheckDomain(double x) const {return (x>0.0)? 1:0;}
double EvalFunction(double x) const {return x*x;}
// Don't need to define operator(), should inherit from AbstractFunction.
};
int main()
{
ConcreteFunction f;
std::cout<<"f(1) = "<<f(2.0)<<std::endl; //OK, returns 4
std::cout<<"f(-1) = "<<f(-1.0)<<std::endl; //Throws runtime error, out of domain.
return 0;
}
I have this class hierarchy where I'm trying to add operator= :
class A
{
public:
virtual void someFunction() = 0;
virtual A& operator=(const A&) = 0;
};
class B : public A
{
public:
void someFunction() {
//implementation
}
A& operator=(const A& o)
{
*ptr = *o.ptr;
return *this;
}
private:
A* ptr;
};
class C : public A
{
public:
void someFunction() {
//implementation
}
A& operator=(const A& o)
{
data = o.data;
return *this;
}
private:
int data; //NOTE: different members that needs to be copied in the operator
};
I understand why this doesn't work. I have a private member in B (that needs to be there) and a function A&operator=(const A&) that needs to be overwritten. Problem is that o is of type A and doesn't have the pointer ptr.
I've tried to dynamic_cast o to type B, but
that wont work since it's constant,
It seems unsafe (if rhs is of type C)
Same issue for class C.
Is there some cleaver work-around?
Clarification of why I need it this way:
class superClass
{
public:
superClass& operator=(const superClass& o)
{
*some_A_type = *o.some_A_type;
}
private:
A* some_A_type;
};
essentially, what I want is an operator= for superClass. I'm not sure where or how to fix it.
You should re-consider your initial design of classes.
Also you should understand:
operator polymorphism (a + b works for both std::string and int)
data type cannot be polymorph by itself because memory layout should be defined
what is abstract class and/or interface
maybe static polymorphism would be useful too
First try to imagine what implication of having assignment between any object of any class within class A. I.e. to store object of B in object of C we should change state of object from C in that way that its characteristics will be equivalent object to original object from B. This can be achieved either by having common memory layout (i.e. all descendants store same data) between all descendants of A or by exposing same behavior in some other way like referencing to original object.
Note that behavior of virtual void someFunction() should also be copied.
Let's try to pull out maximum out of your sample:
// our interface
struct A {
virtual void someFunction() = 0;
// no polymorphic assignment
};
struct B : A {
void someFunction();
B &operator=(const A &o)
{ ptr = &o; return *this; }
private:
A *ptr;
}
struct C : A {
void someFunction();
A &operator=(const C &o)
{ data = o.data; return *this; }
private:
int data;
};
C c, c2;
B b;
A &a = c;
b = c; // ok
b = a; // ok
c = c2; // ok
c = b; // wrong
Or if you still want polymorphic assignment:
// interface. descendants are responsible for maintaining LSP
struct A {
void someFunction()
{ cout << data(); }
virtual int getData() const = 0;
// assignment should result in copying chars and making getData() to behave like in original object
virtual A &operator=(const A &o) = 0;
};
struct B : A {
int getData() const { return ptr->getData(); }
A &operator=(const A &o)
{ ptr = &o; return *this; }
private:
const A *ptr;
};
struct C : A {
int getData() const { return data; }
A &operator=(const A &o)
{ data = o.getData(); return *this; }
private:
int data;
};
P.S. Last variant probably unwanted in real world.
Found in similiar question sugested by TobiMcNamobi:
class B : public A
{
public:
virtual A& operator=(const A& p)
{
*ptr = *o.ptr;
return *this;
}
virtual B& operator=(const B& p)
{
//throw exception
}
};
I am pretty new to C++. Today, I am experiencing some issues in mixing nested classes and interfaces.
I wrote a small (useless) program that will be more effective at explaining my issue than long sentences:
#include <iostream>
#include <vector>
class SomeInterface {
public:
virtual int SomeMethod() = 0;
class reference {
public:
virtual operator int() const = 0;
virtual reference& operator=(int x) = 0;
};
virtual reference operator[](unsigned int pos) = 0;
};
class A : public SomeInterface {
public:
A(unsigned int size) { vec_.resize(size, 0); }
int SomeMethod() { return 1; }
class reference : public SomeInterface::reference {
public:
reference(std::vector<int>::reference ref) : ref_(ref) { }
operator int() const { return (int) this->ref_; }
reference& operator=(int x) { this->ref_ = x; return *this; }
private:
std::vector<int>::reference ref_;
};
reference operator[](unsigned int pos) {
return reference(this->vec_[pos]);
};
private:
std::vector<int> vec_;
};
int main() {
A a(10);
a[5] = 42;
std::cerr << a[5] << std::endl;
return 0;
}
Here, the program compiles fine if I remove the line virtual reference operator[](unsigned int pos) = 0; in the interface. However, I would like the array subscript operator to be part of the interface.
The error message thrown by G++ is invalid abstract return type for member function ‘virtual SomeInterface::reference SomeInterface::operator[](unsigned int)’.
I do understand why it fails. But I can't figure out any way to make something like this work. Can anybody explain why I am doing (or thinking) wrong?
You can not create objects of type SomeInterface::reference, since it is a pure abstract class, and that is what the compiler told you.
You need to return a reference (or a pointer) to such class. Like this :
virtual reference& operator[](unsigned int pos) = 0;
but then :
in derived classes, you shouldn't change the signature of the pure virtual methods. It should stay virtual SomeInterface::reference& operator[](unsigned int pos)
you can not return reference to a temporary object
btw take care how you create objects of such classes. They do not have virtual destructors.
Basically you can't return a reference to something that can never exist. However, you could use a pointer to an abstract class. That pointer will ultimately only be able to point to an instance of a derived class.
It is not clear exactly what you are trying to do. But you might look into Creation Patterns to find something close to what you need