I'm working with code where CustomThreadApi is not modifiable. CustomThreadApi has a ctor that takes a constchar*. I would like to assign MyThreadClass.Name to CustomThreadApi.tName but ofc, CustomThreadApi's ctor runs before MyThreadClass.Name is initialized.
I managed to get around this problem by creating the tName member in CustomThreadApi so I can pass it as the buff argument to GetDefaultNamev2. But how would I pass MyThreadClass.Name without being able to modify the CustomThreadApi class?
#include <iostream>
#include <sstream>
#include <string>
using std::string;
using std::cout;
using std::ostringstream;
// CustomThread is not modifiable (legacy code someone wrote)
struct CustomThreadApi
{
CustomThreadApi(constchar* name) :
tName(name) // Not how it's implemented in the real code
{};
string tName; // Added to make this example work. Doesn't exist in real code.
};
struct MyThreadClass : CustomThreadApi
{
string Name;
// Want to use 'id' to programmatically set MyThreadClass.Name e.g., if id=100, MyThreadClass.Name="MyThread-100"
MyThreadClass(int id) :
Name(GetDefaultNamev2(id, Name)), // Clunky but ok.
CustomThreadApi(GetDefaultNamev2(id, this->tName).c_str()) // Need to call subclass ctor with MyThreadClass.Name already initialized.
{
cout << "Created " << Name << "!\n";
}
string GetDefaultNamev2(int id, string &buff)
{
ostringstream oss;
oss << "MyThread-" << id;
buff = oss.str();
// A little clunky. We'd already set the MyThread's name in the line above. Is there a better way?
return buff;
}
};
int main()
{
MyThreadClass r1(500); // Want r1.Name and r1.tName to be "MyThreadClass-500" after this call.
cout << "r1.tName: " << r1.tName << "\n";
}
The approach is to define a subclass function (GetDefaultNamev2) that generates the needed data (in this class the class name based on id) and writes the name to any "buffer" space.
Since I can't create a buffer space in CustomThreadApi, I can just initialize the buffer space (baseClassBuff) in the subclass. Use GetDefaultNamev2 with this buffer space to pass into the base class.
#include <iostream>
#include <sstream>
#include <string>
using std::string;
using std::cout;
using std::ostringstream;
// CustomThread is not modifiable (legacy code someone wrote)
struct CustomThreadApi
{
CustomThreadApi(constchar* name) : tName(name)
{};
string tName; // Private in actual code. Who knows how 'name' is used.
};
struct MyThreadClass : CustomThreadApi
{
string baseClassBuff;
string Name;
// Want to use 'id' to programmatically set MyThreadClass.Name e.g., if id=100, MyThreadClass.Name="MyThread-100"
MyThreadClass(int id) :
CustomThreadApi(GetDefaultNamev2(id, baseClassBuff).c_str()),
//Name(GetDefaultNamev2(id, Name)) // If CustomThreadApi.tName is inaccessible
Name(this->tName) // If CustomThreadApi.tName is accessible.
{
cout << "Created " << Name << "!\n";
}
string GetDefaultNamev2(int id, string &buff)
{
ostringstream oss;
oss << "MyThread-" << id;
buff = oss.str();
// A little clunky. We'd already set the MyThread's name in the line above. Is there a better way?
return buff;
}
};
int main()
{
MyThreadClass r1(500); // Want r1.Name and r1.tName to be "MyThreadClass-500" after this call.
cout << "r1.tName: " << r1.tName << "\n";
}