How to initialize base class member with subclass member?

I'm working with code where CustomThreadApi is not modifiable. CustomThreadApi has a ctor that takes a const char*. 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?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#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(const char* 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";
}


Created MyThread-500!
r1.tName: MyThread-500
Last edited on
Seems like this would work.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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(const char* 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";
}


Created MyThread-500!
r1.tName: MyThread-500
Last edited on
baseClassBuff is unnecessary. I can just reuse MyThreadClass.Name.
Registered users can post here. Sign in or register to post.