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 have a program written in C++ where the user is able to segment some cells from a microscopy image. When this is done, the program got three overall parameters to change. Those three being feature, classifier and reductionMethod.
Each of these parameters are made as templates which are equal in their initialization. I thought that I could make the following implementation to call this:
if (feature == 1)
{
FastColorIntensityGradientFeature<8> workingFeature();
}
else if (feature == 2)
{
ColorIntensityGradientFeature<8> workingFeature();
}
workingFeature(input, var, var);
But this is not possible, because the workingFeature is initialized in the if-else statement. How can I do this instead? I'm not that used to programming in C++.
One way to make it work is to move your code into a function that has a template parameter taking the feature type you want to deal. Sample:
template <typename IntensityGradientFeature>
void doWork() {
IntensityGradientFeature workingFeature;
workingFeature.doSomething();
}
Then you call this way:
if (feature == 1)
doWork< FastColorIntensityGradientFeature<8> >();
else if (feature == 2)
doWork< ColorIntensityGradientFeature<8> >();
Both of the templates can have a common base class, then you can create a pointer of type base, and then create the desired child in the if clause.
class base
{
public:
virtual void workingFeature(input, var, var);
};
template<int num>
class FastColorIntensityGradientFeature : public base
{
public:
virtual void workingFeature(input, var, var);
};
template<int num>
class ColorIntensityGradientFeature: public base
{
public:
virtual void workingFeature(input, var, var);
};
and then change your if clause to:
base * choice;
if (feature == 1)
{
choice = new FastColorIntensityGradientFeature<8>;
}
else if (feature == 2)
{
choice = new ColorIntensityGradientFeature<8>;
}
else
{
// some error handling
}
choice->workingFeature(input, var, var);
You didn't specify the argument types for your function, but obviously they will need to be there in the class definitions.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have decided to challenge myself into creating a simple Risk-type strategy game in C++. The game will have multiple factions fighting for control of territories using various types of troop/unit.
I am only in the basic outlining of the game, but one basic idea I have is to create a class for each faction:
class Windows {
private:
bool isWindows = true;
// Characteristics etc.
};
class Mac {
private:
bool isMac = true;
// Characteristics etc.
};
class Linux {
private:
bool isLinux = true;
// Characteristics etc.
};
After which individual classes of unit will inherit certain characteristics of the faction which it is associated, such as: class Penguin: private Linux {//Code};
Is this the best way of doing this, or is there a better way with fewer classes?
If factions have similarities use a base class and them make individual subclasses for each faction and faction class as base class for units.
It sounds like the different factions have different settings for the same set of characteristics which suggests that you should have one Faction class and have different instances of Faction.
I assume you need only one instance of each faction. They can be a kind of singleton. The idiomatic way of doing singletons in c++ is using a function returning a reference to a local static variable:
class Faction {
// Characteristics etc.
};
const Faction& windows() {
static Faction f{ /* initialize with windows characteristics */ };
return f;
}
const Faction& mac() {
static Faction f{ /* initialize with mac characteristics */ };
return f;
}
const Faction& linux() {
static Faction f{ /* initialize with linux characteristics */ };
return f;
}
Then a class like Penguin, rather than inheriting from a Faction can use the linux instance of Faction. It could, for example, hold a reference to its faction:
class Penguin {
const Faction& faction = linux();
public:
void someAction() {
// use faction reference
}
};
I suggest you try to avoid checks like "isLinux" as it makes code brittle and instead rely on characteristics of the faction object itself. The less code that has to change if you introduce a new faction the better. If you really do need to detect the type of a faction then because the faction instances are singleton you can compare the address:
bool isWindows(const Faction& f) { return &f == &windows(); }
bool isLinux(const Faction& f) { return &f == &linux(); }
bool isMac(const Faction& f) { return &f == &mac(); }
If you do this it is probably a good idea to prevent a Faction object from being copied so you can rely on it being at the right address:
class Faction {
// ...
// uncopyable
Faction(const Faction&) = delete;
Faction& operator=(const Faction&) = delete;
};
Live demo.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
The task I have at hand is to write a system to test out n different algorithms in a library - all doing the same broad task but with different methodologies. I thought about creating a main class to which I send an argument defining the algorithm to be used. This main class in-turn calls the taskAlgorithm class passing on the parameter to be used and the required input parameters for the algorithm to be used. The taskAlgorithm class should then instantiate the specific algorithm class to be used in its constructor. taskAlgorithm::Process should run the algorithm and store the result and taskAlgorithm::Result should return the result.
I am stuck on figuring out how to write this taskAlgorithm class. In the constructor of this class, based on the algorithmCode parameter I want to instantiate an object of the specific algorithm, however, all algorithm classes are different and do not necessarily have a common base class. What's the best way to tackle this problem?
Specifically in
taskAlgorithm::taskAlgorithm(int algorithmCode, int argument1){
if(algorithmCode == 1){
//instantiate the algorithm1 object
}
else if(algorithmCode == 2){
//instantiate algorithm2 object
}
}
how should I instantiate objects for each of different algorithm classes if they don't necessarily share a common base class?
If they are related algorithms, perhaps you can think of the "common" interface that, if it existed, would be capable of calling into any of the algorithms if you knew which parts to use, or which transformations to perform.
This would allow you to write a wrapper interface to all the algorithms, so they can be called uniformly. Each wrapper could "know" how to take its inputs to call the underlying algorithm that it wraps. I didn't do it here, but you could do the same for the return value.
For example Algorithm A is a sort taking a pair of iterators into a vector of ints, and a comparator, while Algorithm B is a different kind of sort, taking a pointer to an int array, a length, and a comparator.
class Algo {
public:
using Iter = std::vector<int>::iterator;
using Compare = ...;
virtual void call(Iter b, Iter e, Compare comp) = 0;
virtual ~Algo() = default;
};
class A : public Algo {
void call(Iter b, Iter e, Compare comp) override {
algorithmA(b, e, comp);
}
};
class B : public Algo {
void call(Iter b, Iter e, Compare comp) override {
if (b != e) {
algorithmB(&*b, std::distance(b, e), comp);
}
}
};
Now you can wrap algorithm A with class A, and algorithm b with class B, and they are invoked identically, and the wrappers share a common base class so they can be used polymorphicly.
Of course, you can't templatize virtual functions so the iterator type is fixed, but the example here is about making a wrapper hierarchy that normalizes the interface to the algorithms. Then you can avoid a nasty switch statement (which requires editing working code every time you add a new algorithm.) With a class wrapper approach, just wrap new algorithm with a new wrapper class and it should just fit into any system that already works with the existing algorithms (provided you don't change the signature of the virtual call() function).
This isn't exactly answering your question but I think it's close enough to maybe be useful. :)
According to the comments under the question, I think in this case this is the only reasonable approach:
// structure of all possible arguments to all your algorithms
struct AlgorithmArgs {
int arg1;
int arg2; // etc ...
}
class AlgorithmWrapper {
public:
AlgorithmWrapper(int algorithmId, const AlgorithmArgs args) {
if (algorithmId == 1) {
algorithm_ = Algorithm1{}; // or whatever you do to construct that Algorithm1 object
} else if ( /* etc ... */ ) {}
}
void someMethodToUnifyAllAlgorithmInterfaces1();
void someMethodToUnifyAllAlgorithmInterfaces2();
void someMethodToUnifyAllAlgorithmInterfaces3();
private:
std::variant<Algorithm1, Algorithm2, Algorithm3> algorithm_;
};
taskAlgorithm::taskAlgorithm(int algorithmCode, int argument1){
AlgorithmArgs args;
args.arg1 = argument1;
algorithmWrapperPtr_ = new AlgorithmWrapper(algorithmCode, args);
executeSomeUnifiedProcedureCommonForAllAlgorithms();
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Hello my question is regarding if its possible to use the factory pattern for classes with same number of arguments in their constructor but different types. For example, I have an interface called IVerify. I have 2 classes that implement them, NameVerifier, which takes in a String name in its constructor, and IntegerVerifier, which takes in an int num in its constructor. Is it possible to do the factory pattern in this case?
Could we use IVerify Factory.CreateNameVerifier(string) and IVerify Factory.createIntegerVerifier(int) Is it still considered as a factory pattern?
Additional note: Im using c++
If there are many versions of NameVerifier and IntegerVerifier then your solution is still a Factory Pattern since you will be abstracting which class to instantiate inside CreateNameVerifier and CreateIntegerVerifier.
But if Verifiers are unique w.r.t to the type of Argument that they take i.e., there is only one NameVerifier and only one IntergerVerifier and they differ because of their types then your existing solution is just creating a sort of wrapper to create objects/Verifiers. In such case it should be something like this:
Reference: Factory Pattern
class IVerify
{
};
class CNameVerifier : public IVerify
{
};
class CIntegerVerifier : public IVerify
{
};
class CVerifierFactory
{
enum TYPE
{
STRING,
INTEGER
};
template<typename T>
IVerify* CreateVerifier(const CVerifierFactory::TYPE &_enumType, T _Parameter)
{
IVerify *pVerifier = NULL;
switch(_enumType)
{
case (CVerifierFactory::STRING)
pVerifier = new CNameVerifier(_Parameter);
break;
case (CVerifierFactory::INTEGER)
pVerifier = new CIntegerVerifier(_Parameter);
break;
}
return pVerifier;
}
};
CVerifierFactory g_oFactory;
IVerify *pVerifier = g_oFactory.CreateVerifier(CVerifierFactory::STRING, "Alex");
if(pVerifier != NULL)
{
//use pVerifier
}
Note: Strict Type Checking of arguments _Parameter are not done before creating Verifiers. You can extend the number of arguments for object creation using Variadic Template/Parameter pack.
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
I have a function where I want to add pointers into a vector.
#include "Car.hpp"
using namespace std;
bool CarManagementSystem::addCar(Car::CarType new_car_type) {
if (Car::CarType(new_car_type) == (Invalid)) {
return false;
}
else{
new Car::CarType(new_car_type);
carVector.push_back(Car::CarType(new_car_type));
return true;
}
}
The push_back command is giving me a lot of grief as in to what form I want the constraints to be in. I want to be able to use this function to create different types of my object Car, however am unsure how to do this.
The car class is purely virtual base class for all my different types of cars.
#include "Car.hpp"
Car::~Car() {
}
Car::CarType Car::type() const {
return AT_INVALID;
}
class CarSystem {
private:
double Balance;
double CarCost;
std::vector<Car*> carVector;
...
Your vector should be a vector of Car*:
std::vector<Car*> carVector;
The vector should be filled with concrete versions of the cars, meaning classes that are derived from base class Car:
class Van : public Car
{
...
};
...
Van* newVan = new Van();
carVector.push_back(newVan);
Here Van* is also a Car*.
Make sure that you delete the contents of the vector at some point, or use smart pointers.
A better solution might be to have an enum inside the Car class that states the type of car, and then you don't need to deal with pointers.
The trouble you have is that this code fragment doesn't do what you think:
new Car::CarType(new_car_type);
carVector.push_back(Car::CarType(new_car_type));
The first line creates a pointer to a new CarType object (an enum, an int, I don't know how you've defined it). This pointer is immediately lost and will cause memory leaks.
The second line tries to push_back a CarType object, which obviously is not a pointer.
What you are missing in your code is a factory function, which takes a CarType and which constructs a concrete car. It is not clear in your code if Car is an abstract type that can't be instantiated, or if it is a concrete class with some variations around the CarType.
If Car has a constructor that takes the CarType as parameter you'd need to do something like:
bool CarManagementSystem::addCar(Car::CarType new_car_type) {
...
else{
carVector.push_back(new Car(new_car_type));
return true;
}
}
But if Car is an abstract type with derived classes, you'd go for something like:
bool CarManagementSystem::addCar(Car::CarType new_car_type) {
Car *c;
switch (new_car_type) {
case AT_SUV:
c = new SUV; // if SUV would be a class derived from Car
break;
case AT_RACING_CAR:
...
case AT_INVALID:
default:
return false;
}
carVector.push_back(c);
return true;
}
You may in this case be interested in a nice factory method pattern implementation such as the one explained in this tutorial.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm writing a physics engine in C++ and I've come to a stop, namely how I should design the class hierarchy. What I'm specifically concerned about is the World and Body classes. Body should expose some details to World that World then can work on. But at the same time, I don't want users to be able to access all of those properties of Body. But I still want users of the engine to be able to change some things in a body. For example, its position. How would you structure this in terms of classes?
Define an interface (i.e. a pure virtual class) that specifies what functions you want exposed from Body. Have Body implement that inteface.
Allow that interface, and not Body to be used from World.
This pattern is called composition.
Recently, I've solved a similar problem by introducing a special interface for the restricted operations, and inheriting protectedly from it. Like this:
struct RestrictedBodyFunctions
{
virtual void step() = 0;
virtual Body& asBody() = 0;
};
struct Body : protected RestrictedBodyFunctions
{
static std::unique_ptr<Body> createInWord(World &world)
{
auto Body = std::unique_ptr<Body>{new Body()};
world.addBody(*body); // cast happens inside Body, it's accessible
return std::move(body);
}
std::string getName() const;
void setName(std::string name);
protected:
void step() override
{ /*code here*/ }
Body& asBody() override
{ return *this; }
};
struct World
{
void addBody(RestrictedBodyFunctions &body)
{
m_bodies.push_back(&body);
}
void step()
{
for (auto *b : m_bodies)
{
myLog << "Stepping << " b->asBody().getName() << '\n';
b->step();
}
}
private:
std::vector<RestrictedBodyFunctions*> m_bodies;
};
That way, users can create Body objects using createInWorld, but they only get a handle to (the public part of) Body, while the World gets its handle to RestrictedBodyFunctions.
Another option you have is to reverse the above idea - provide a restricted public interface PublicBody, and have Body derive from PublicBody. Your internal classes will use the full Body, while factory functions make sure only PublicBody-typed handles are available to the clients. This alternative is a more simple design, but provides less control over who can access the full functionality.