I have this sample program that works but isn't producing the desired results...
Here is the current output:
Output
class Component_00 class Component_01 class Component_02
Successfully connected class Component_01 to class Component_00
Successfully connected class Component_02 to class Component_00
Component class Component_02 already exists in class Component_00!
Successfully connected class Component_02 to class Component_01
And this would be my desired output:
Wire_00 Wire_01 Wire_02
Successfully connected Wire_01 to Wire_00
Successfully connected Wire_02 to Wire_00
Component Wire_02 already exists in Wire_00!
Successfully connected Wire_02 to Wire_01
This is a two-fold question but they are related to the same problem...
The first part is I don't want the word class
to be printed before the actual class name.
The second part is I don't want the base class's name to be printed as this is an abstract class. I want the derived class's name to be printed instead...
What do I need to do to resolve this?
-Note- I am using Visual Studio 2017, but this should work agnostic of any compiler used, it should be portable.
Here is all of my relevant source code:
main.cpp
#include <iostream>
#include <exception>
#include "Wire.h"
int main() {
try {
Wire w1, w2, w3;
std::cout << w1.id() << " " << w2.id() << " " << w3.id() << "\n";
w1.connect(&w2);
w1.connect(&w3);
w1.connect(&w3);
w2.connect(&w3);
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Component.h
#pragma once
#include <list>
#include <map>
#include <memory>
#include <string>
#include <typeinfo>
class Component {
private:
std::string id_ = std::string( typeid(*this).name() ) + "_0";
std::list<Component*> components_;
public:
Component() {
updateId();
}
virtual ~Component() {}
std::string& id() { return id_; }
void connect(Component* other) {
for (auto& l : components_) {
if (other->id_ == l->id()) {
std::cout << "Component " << other->id_ << " already exists in " << id_ << "!\n";
return;
}
}
components_.emplace_back( other );
std::cout << "Successfully connected " << other->id() << " to " << id_ << "\n";
}
virtual void propagate() = 0;
private:
void updateId() {
static int i = 0;
id_.append( std::to_string(i++) );
}
};
Wire.h
#pragma once
#include "Component.h"
class Wire : public Component {
private:
public:
Wire() {}
virtual ~Wire() {}
virtual void propagate() override {
return;
}
};
Edit
I modified my base and derived class to use a helper function in generating the class name...
Here are the modified classes:
Component.h
#pragma once
#include <list>
#include <map>
#include <memory>
#include <string>
#include <typeinfo>
template<class T>
constexpr const std::string generateName(T t) {
return std::string(typeid(t).name());
}
class Component {
protected:
std::string id_ = "";
std::list<Component*> components_;
public:
explicit Component(const std::string& id) : id_{ id } {}
virtual ~Component() {}
std::string& id() { return id_; }
void connect(Component* other) {
for (auto& l : components_) {
if (other->id_ == l->id()) {
std::cout << "Component " << other->id_ << " already exists in " << id_ << "!\n";
return;
}
}
components_.emplace_back( other );
std::cout << "Successfully connected " << other->id() << " to " << id_ << "\n";
}
virtual void propagate() = 0;
protected:
void updateId() {
static int i = 0;
id_.append( "_" + std::to_string(i++) );
}
};
Wire.h
#pragma once
#include "Component.h"
class Wire : public Component {
private:
public:
Wire() : Component(generateName(this)) {
updateId();
};
virtual ~Wire() {}
virtual void propagate() override {
return;
}
};
The main cpp file has not changed...
Here is the new output...
class Wire *_0 class Wire *_1 class Wire *_2
Successfully connected class Wire *_1 to class Wire *_0
Successfully connected class Wire *_2 to class Wire *_0
Component class Wire *_2 already exists in class Wire *_0!
Succesfully connected class Wire *_2 to class Wire *_1
This is now giving me the desired base class's name, however, it is still printing the world class
before it in which I don't want, and now it is also appending a space followed by an *
in which I also don't want...