Fails to allocate derivative class to base class pointer? - c++

I have a AbstractFactory, WinFactory and IOSFactory classes.
AbstactFactory inheritences WinFactory and IOSFactory as the following:
class IOSFacetory {
private:
IOSRectButton *_rectbtn;
IOSCircularButton *_circbtn;
public:
IOSFacetory() : _rectbtn(NULL), _circbtn(NULL) {} // set rectbtn to null
IOSRectButton* getIOSRectBtn () {
if(!_rectbtn) _rectbtn = new IOSRectButton;
return _rectbtn;
}
IOSCircularButton* getIOSCircBtn() {
if(!_circbtn) _circbtn = new IOSCircularButton;
return _circbtn;
}
~IOSFacetory() {
if(_rectbtn) delete _rectbtn;
if(_circbtn) delete _circbtn;
}
};
class WinFacetory {
private:
WinRectButton *_rectbtn;
WinCircularButton *_circbtn;
public:
WinFacetory() : _rectbtn(NULL), _circbtn(NULL) {} // set rectbtn to null
WinRectButton* getWinRectBtn () {
if(!_rectbtn) _rectbtn = new WinRectButton;
return _rectbtn;
}
WinCircularButton* getWinCircBtn() {
if(!_circbtn) _circbtn = new WinCircularButton;
return _circbtn;
}
~WinFacetory() {
if(_rectbtn) delete _rectbtn;
if(_circbtn) delete _circbtn;
}
};
class AbstractFactory : public WinFacetory, public IOSFacetory {
public:
AbstractFactory(){}
};
in the main function, I'm trying to set a IOSFactory into a AbstractFactory Pointer:
#include "AbstractFactory.h"
int main() {
#ifdef _WIN
AbstractFactory* factory = new WinFacetory;
#else
AbstractFactory* factory = new IOSFacetory;
#endif
std::cin.get();
return 0;
}
It doesn't work and I get the following compilation error:
IntelliSense: a value of type "IOSFacetory *" cannot be used to initialize an entity of type "AbstractFactory *.
I guess I have a minor error but I can't figure it out. I'd like to get helped. thanks!

You should reverse your inheritance relations. AbstractFactory should be a base class of both IOSFactory and WinFactory.
Remember to declare a virtual destructor in the base class.

You should derive WinFacetory and IOSFacetory from AbstractFactory. Now you do it contrariwise.

Related

Correct pattern for nested private class that inherit from outer class

I am trying to implement a pattern in C++ where a nested private class inherits from the outer class and the private class is instantiated via a static factory method in the outer abstract class.
I have this code now, that compiles, but I am not sure whether I did it correctly.
Search.h:
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static Search & create();
virtual int doIt() = 0;
};
class Search::Implementation: public Search {
int doIt();
};
}
Search.cpp:
#include "Search.h"
using namespace ns_4thex;
Search & Search::create() {
return *(new Search::Implementation());
}
int Search::Implementation::doIt() {
return 0;
}
Thought?
A static factory method always returns a pointer type. So the create function should return a pointer or smart pointers in modern c++.
The declaration:
static std::unique_ptr<Search> create();
The definition:
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
The complete code may like this:
#include <memory>
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static std::unique_ptr<Search> create();
virtual int doIt() = 0;
};
class Search::Implementation : public Search {
int doIt();
};
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
int Search::Implementation::doIt() { return 0; }
} // namespace ns_4thex
Your example has potentially a memory leak. The factory pattern should return a pointer type instead of the reference type. The caller using it can free the allocated memory
Search* Search::create() {
return new Search::Implementation();
}

Union of pointers of objects (use only one type for different instances)

I've now the following code snipplet in a class:
DrvClassA *drv_a_obj;
DrvClassB *drv_b_obj;
DrvClassC *drv_c_obj;
if ( use_drv_a ) {
drv_a_obj = new DrvClassA(args);
}
if ( use_drv_b ) {
drv_b_obj = new DrvClassB(args);
}
if ( use_drv_c ) {
drv_c_obj = new DrvClassC(args);
}
and want to convert it somehow, to use only one variable for the created driver instance:
this->Drv = new DrvClassA(args);
}
if ( use_drv_b ) {
this->Drv = new DrvClassB(args);
}
if ( use_drv_c ) {
this->Drv = new DrvClassC(args);
}
I thought about creating an union like this, but I'm getting errors upon compile.
error: cannot convert 'DrvClassA*' to 'MainClass::DRIVERS*' in assignment
union DRIVER {
DrvClassA *drv_a_obj;
DrvClassB *drv_b_obj;
DrvClassC *drv_c_obj;
}
DRIVER *Drv;
Is this achievable somehow? What am I missing?
What you might be looking for is polymorphism:
Live sample
class Drv{
public:
virtual ~Drv(){};
};
class DrvClassA : public Drv{};
class DrvClassB : public Drv{};
class DrvClassC : public Drv{};
int main(){
Drv* a = new DrvClassA(); // Drv a = DrvClassA();
Drv* b = new DrvClassB(); // Drv b = DrvClassB();
Drv* c = new DrvClassC(); // Drv c = DrvClassC();
}
Better yet use smart pointers to avoid memory leaks:
Live sample
#include <memory>
using std::unique_ptr;
class Drv{
public:
virtual ~Drv(){};
};
class DrvClassA : public Drv{};
class DrvClassB : public Drv{};
class DrvClassC : public Drv{};
int main(){
unique_ptr<Drv> a(new DrvClassA);
unique_ptr<Drv> b(new DrvClassB);
unique_ptr<Drv> c(new DrvClassC);
}
Yes, you can have a union of pointers.
What am I missing?
You've failed to specify which member of the union to assign. Correct syntax:
this->Drv->drv_a_obj = new DrvClassA(args);
P.S. You may later be interested in which of the union members was assigned. You'll find that this is not possible. The solution for that is to us a tagged union instead, such as std::variant.
P.P.S: A possibly better design would be to use inheritance. this->Drv could be a pointer to base object instead of a union.
P.P.P.S. Don't use owning bare pointers. You'll end up with memory leaks and undefined behaviour. Use RAII containers and smart pointers instead.
union is mostly only needed to implement variant.
So you might use:
using DRIVER = std::variant<std::unique_ptr<DrvClassA>,
std::unique_ptr<DrvClassB>,
std::unique_ptr<DrvClassC>>;
// or
//using DRIVER = std::variant<DrvClassA*, DrvClassB*, DrvClassC*>;
with usage
DRIVER Drv;
// ...
Drv = std::make_unique<DrvClassA>(args);
// ...
std::visit(overloaded{[](const std::unique_ptr<DrvClassA>& ptr){ ptr->funcA(); },
[](const auto& ptr){ ptr->common_interface(); }}, // DrvClassB or DrvClassC
Drv);
But Polymorphism might be more appropriate:
struct DRIVER
{
virtual ~DRIVER() = default;
virtual void some_common_function() = 0;
};
struct DrvClassA : DRIVER
{
void some_common_function() override { /*..*/ }
};
struct DrvClassB : DRIVER
{
void some_common_function() override { /*..*/ }
};
struct DrvClassC : DRIVER
{
void some_common_function() override { /*..*/ }
};
and then
std::unique_ptr<DRIVER> Drv;
// ...
Drv = std::make_unique<DrvClassA>(args);
Drv->some_common_function();

How do I unit test a factory?

I unit test my classes by giving all my classes an interface. These interfaces have in turn their own mocks.
But lets say I have the following:
class IData
{
GetData()
}
class IOnScreenDataCalculator
{
Calculate(IData)
}
class OnScreenData : IOnScreenData
{
OnScreenData(PTR_T(IData), PTR_T(IOnScreenDataCalculator))
enter code here
GetOnScreenData()
}
Now lets say that I wish to have a number of factories for different types of data and calculators. How can I unit test these factories where my factories are as follows:
OnScreenBlueDataForWideScreenFactory
{
PTR:T(IOnScreenData) Create()
{
PTR_T(Data) data = ptr_t(new BlueData());
PTR_T(IOnScreenDataCalculator) calculator = ptr_t(new WideScreenDataCalculator());
PTR_T(IOnScreenData) onScreenData = ptr_t(new WideScreenDataCalculator(data, calculator ));
return onScreenData;
}
}
Thanks for your help,
Barry.
I am not sure the code snippets are really c++, but the example should be something like this :
class ExampleIface
{
public:
virtual ~ExampleIface() {}
virtual void a() = 0;
};
class Example1: public ExampleIface
{
public:
virtual ~Example1() {}
virtual void a()
{
// something
}
};
class ExampleFactory
{
public :
typedef ExampleIface * ExamplePtrType; // can be shared_ptr instead
static ExamplePtrType Create( /*params?*/)
{
ExamplePtrType p( new Example1 );
return p;
}
private:
ExampleFactory();
~ExampleFactory();
};
and the unit test:
void test_Create()
{
ExampleFactory::ExamplePtrType p = ExampleFactory::Create();
Example1 *realType = dynamic_cast< Example1* >( p );
TS_ASSERT( NULL != realType ); // if you use cxxtest
}
I'd call Create() and verify that I get a properly constructed object with the right constituent types.

Instantiating objects and object members

For some reason the following doesn't crash like my program does, but I'm pretty sure it's similar in design. For one, the output's not correct. It outputs something similar to:
0x537ff4 5471612
While the main program outputs (nil) for the pointer address.
The key to the problem might be display_ in Drv.
Here's the code:
#include <iostream>
#include "debug.h"
class LCDText {
public:
int rows_;
LCDText() { rows_ = 10; };
};
class Generic {
LCDText *lcdText_;
public:
Generic(LCDText *lcdText) { lcdText_ = lcdText; };
void Setup() {
Error("%p %d", lcdText_, lcdText_->rows_);
}
};
class Display : public LCDText {
Generic *visitor_;
public:
Display(Generic *visitor) { visitor_ = visitor; };
};
class Drv : public Generic {
Display *display_;
public:
Drv() : Generic((LCDText *)display_) {
display_ = new Display((Generic *)this);
};
~Drv() { delete display_; };
};
int main()
{
Drv drv;
drv.Setup();
return 0;
}
This code:
Drv() : Generic((LCDText *)display_) {
display_ = new Display((Generic *)this);
};
first runs the parent class's ctor, with a yet-uninitialized value of display_, then independently sets display_, but, too late to change the parent class. So the pointer held by the parent class will never be set correctly. I guess you need to add a protected setter method (or make the parent-class-held pointer member itself protected).
Your Drv constructor passes the garbage, uninitialized value of Drv::display_ to Generic before initializing it in the constructor body. You can do a couple of things here, my preferred would be:
class Drv : public Generic {
Display* display() { return (Display*)lcdText_; }
public:
Drv() : Generic(new Display(this)) {}
}
Because it doesn't result in a duplicate field, but you can also have an abstract getLcdText() in Generic, which could be better if you are already using virtual methods.
In the constructor for Drv, when you first call the constructor for Generic display_ is still uninitialized. You don't new the pointer until later.

How to declare factory-like method in base class?

I'm looking for solution of C++ class design problem. What I'm trying to achieve is having static method method in base class, which would return instances of objects of descendant types. The point is, some of them should be singletons. I'm writing it in VCL so there is possibility of using __properties, but I'd prefer pure C++ solutions.
class Base {
private:
static Base *Instance;
public:
static Base *New(void);
virtual bool isSingleton(void) = 0;
}
Base::Instance = NULL;
class First : public Base { // singleton descendant
public:
bool isSingleton(void) { return true; }
}
class Second : public Base { // normal descendant
public:
bool isSingleton(void) { return false; }
}
Base *Base::New(void) {
if (isSingleton())
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
else
return new /* descendant constructor */;
}
Arising problems:
how to declare static variable Instance, so it would be static in descendant classes
how to call descendant constructors in base class
I reckon it might be impossible to overcome these problems the way I planned it. If so, I'd like some advice on how to solve it in any other way.
Edit: some minor changes in code. I have missed few pointer marks in it.
Just to check we have our terminologies in synch - in my book, a factory class is a class instances of which can create instances of some other class or classes. The choice of which type of instance to create is based on the inputs the factory receives, or at least on something it can inspect. Heres's a very simple factory:
class A { ~virtual A() {} };
class B : public A {};
class C : public A {};
class AFactory {
public:
A * Make( char c ) {
if ( c == 'B' ) {
return new B;
}
else if ( c == 'C' ) {
return new C;
}
else {
throw "bad type";
}
}
};
If I were you I would start again, bearing this example and the following in mind:
factorioes do not have to be singletons
factories do not have to be static members
factories do not have to be members of the base class for the hierarchies they create
factory methods normally return a dynamically created object
factory methods normally return a pointer
factory methods need a way of deciding which class to create an instance of
I don't see why your factory needs reflection, which C++ does not in any case support in a meaningful way.
Basing this on the answer by #Shakedown, I'll make Base be templated on the actual type, using the CRTP:
template <class T>
class Base
{
public:
static std::auto_ptr<Base<T> > construct()
{
return new T();
}
};
class First : public Base<First>
{
};
class Second : public Base<Second>
{
};
This is nice because construct is now once again a static member. You would call it like:
std::auto_ptr<First> first(First::construct());
std::auto_ptr<Second> second(Second::construct());
// do something with first and second...
You can create a Singleton class and a NonSingleton class, and make all the descendants inherit one of them.
class Base {
public:
static Base *New() = 0;
}
class SingletonDescendant: public Base {
public:
*Base::New() {
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
}
private:
static Base *Instance;
}
SingletonDescendant::Instance = NULL;
class NonSingletonDescendant: public Base {
public:
*Base::New() {
return new;
}
}
class First : public SingletonDescendant{ // singleton descendant
}
class Second : public NonSingletonDescendant{ // normal descendant
}
It solves the issues that you raised:
How to declare static variable Instance, so it would be static in descendant classes: It exists only in the SingletonDescendant class.
How to call descendant constructors in base class: Using the New function
I have to write construct() method in every descendant; I consider it redundant, as it is obvious what it has to do: Now it is only in SingletonDescendant and NonSingletonDescendant.
How about something like this:
class Base
{
public:
virtual Base construct() = 0;
};
class First : public Base
{
public:
Base construct(){ return First(); // or whatever constructor }
};
class Second : public Base
{
public:
Base construct(){ return Second(...); // constructor }
};