I'm trying to follow DRY and I want to put initialization of a new class in function but there is one problem. My class is a parent class and I'm initializating new derived class in this function.
Samples:
Class declaration:
#include <iostream>
class parent
{
private:
int m_number;
public:
parent() {}
virtual void say_hello() { std::cout << "Hello. This is parent class!" << std::endl; }
~parent() {}
};
class derived1 : public parent
{
public:
derived1(){}
void say_hello() override { std::cout << "Hello. This is first derived class!" << std::endl; }
~derived1(){}
};
class derived2 : public parent
{
public:
derived2() {}
void say_hello() override { std::cout << "Hello. This is second derived class!" << std::endl; }
~derived2() {}
};
Enum states:
enum OutputMethod
{
STATE_NONE,
STATE_CLASS,
STATE_EXIT
};
Actions for testing:
#include <Windows.h>
#define VK_L_C 0x43
#define VK_L_N 0x4E
void action(OutputMethod &state)
{
if (GetKeyState(VK_L_C) < 0)
{
state = STATE_CLASS;
}
else if (GetKeyState(VK_L_N) < 0)
{
state = STATE_NONE;
}
else if (GetKeyState(VK_ESCAPE) < 0)
{
state = STATE_EXIT;
}
}
Main:
#include <iostream>
#include <string>
int main(void)
{
derived1 *p_derived = nullptr;
OutputMethod out_method;
out_method = STATE_NONE;
while (out_method != STATE_EXIT)
{
// Actions (C-class, N-none, ESC-endloop)
action(out_method);
//--------BEGINING of desired function----------
if (out_method == STATE_NONE)
{
std::cout << "Hello from main!" << std::endl;
}
else if (out_method == STATE_CLASS)
{
if (p_derived == nullptr)
{
// There is the problem (derived1 name should be variable)
p_derived = new derived1();
}
p_derived->say_hello();
}
if (out_method == STATE_NONE)
{
if (p_derived != nullptr)
{
delete p_derived;
p_derived = nullptr;
}
}
//-------------END of desired function----------
}
if (p_derived != nullptr)
{
delete p_derived;
p_derived = nullptr;
}
std::string exit = "";
std::getline(std::cin, exit);
return 0;
}
I'm not sure how to do it.
I've tried to make a function to deal with this problem:
void output_state(parent *p_variable, parent* p_new, OutputMethod state_0, OutputMethod state_1, OutputMethod &state)
{
if (state == state_0)
{
std::cout << "Hello from main!" << std::endl;
}
else if (state == state_1)
{
if (p_variable == nullptr)
{
// There is the problem (p_new is not a name var but a new object init)
p_variable = p_new;
}
p_variable->say_hello();
}
if (state == state_0)
{
if (p_variable != nullptr)
{
delete p_variable;
p_variable = nullptr;
}
}
}
Calling in main:
...
derived1 *p_derived = nullptr;
OutputMethod out_method;
out_method = STATE_NONE;
while (out_method != STATE_EXIT)
{
// Actions (C-class, N-none, ESC-endloop)
action(out_method);
output_state(p_derived, new derived1(), STATE_NONE, STATE_CLASS, out_method);
}
...
But the problem is that I don't want to init a new object everytime I call the function and I'm not sure how to make the check to be able to call the function but at the same time preventing initializing a new object.
Am I missing something?
P.S: Sorry for the long code but when I post a short code, I get replies that people cannot read my mind but if I post all the necessary parts, I get replies that the code is too long and unreadable.
It seems that you want your function to produce an object of given type. A template
can do that:
template<class ObjType>
OutputMethod output_state( parent *p_variable, OutputMethod state_0, OutputMethod state_1, OutputMethod state ) {
if ( state == state_0 ) {
std::cout << "Hello from main!" << std::endl;
}
else if ( state == state_1 ) {
if ( ! p_variable ) {
p_variable = new ObjType{};
}
p_variable->say_hello();
}
if ( state == state_0 ) {
if ( p_variable ) {
delete p_variable;
p_variable = nullptr;
}
}
return state;
}
And in main:
while ( out_method != STATE_EXIT ) {
// Actions (C-class, N-none, ESC-endloop)
action(out_method);
out_method = output_state<Derived1>( p_derived, STATE_NONE, STATE_CLASS, out_method );
}
Notice that I left p_variable
as raw pointer, but it is largely safer to use std::unique_ptr<>
.