如何在 class B 的构造函数中实例化 C++ class A 以便其对象可供成员函数使用

How can I instantiate C++ class A in the constructor of class B such that its object is available to the member functions

我的大部分背景都在 Python,我正在尝试重新学习 C++,因为它适用于像 Arduino 这样的微控制器板。

我创建了一个名为 DigitalGPIOPin 的独立 C++ class。我还有另一个名为 DigitalRGBPin 的 class,它需要在构造函数中实例化 DigitalGPIOPin class 的 3 个对象,并与其成员函数共享对对象的访问。这可能用 C++ 实现吗?

到目前为止,我正在尝试用一个简化的案例来解决这个问题,但是我收到了代码下方显示的错误,这表明成员函数 initialize_rgb_pin() 无法访问对象。

// GPIOPin.hpp file
class DigitalGPIOPin
{
public:
    int id;  // Pin identifier
    int io   // INPUT or OUTPUT
    DigitalGPIOPin(int identifier, int io_type);
    void initialize_pin();
};
// -----------------------------------------------------------------

class DigitalRGBPin
{
public:
    int red_id, green_id, blue_id
    DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
    void initialize_rgb_pin();
};
// =================================================================
// =================================================================

// GPIOPin.cpp file
DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type)
{
    id = identifier;
    io = io_type;
}

void
DigitalGPIOPin::initialize_pin()
{
    if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
        pinMode(id, io);
    }
    else {
        Serial.println("Pin mode not recognized");
    }
}
// -----------------------------------------------------------------

DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier)
{
    red_id = red_identifier;
    green_id = green_identifier;
    blue_id = blue_identifier;
    DigitalGPIOPin red_pin(red_identifier, OUTPUT);
    DigitalGPIOPin green_pin(green_identifier, OUTPUT);
    DigitalGPIOPin blue_pin(blue_identifier, OUTPUT);
}
// -----------------------------------------------------------------

void
DigitalRGBPin::initialize_rgb_pin()
{
    red_pin.initialize_pin();
    /* Commented out lines below to focus on problem.
       The compiler does not recognize red_pin, because it
       was not defined as a public variable.  So how can I
       define this without having to re-write the entire
       DigitalGPIOPin class as a nested class within DigitalRGBPin.
       This would effectively put me in a position where I have to define
       the class twice, since I still need it as a standalone class. 
    */
    // green_pin.initialize_pin();
    // blue_pin.initialize_pin();
}

这会产生以下错误:

error: red_pin was not declared in this scope

我认为您希望将三个 DigitalGPIOPin 对象声明为 DigitalRGBPin class 的成员变量,并作为构造函数的初始化列表的一部分进行初始化,如下所示:

class DigitalRGBPin
{
public:
    int red_id, green_id, blue_id;
    DigitalGPIOPin red_pin;
    DigitalGPIOPin green_pi;
    DigitalGPIOPin blue_pin;

    DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
    void initialize_rgb_pin();
};
// =================================================================
// =================================================================

DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier)
    : red_pin(red_identifier, OUTPUT)
    , green_pin(green_identifier, OUTPUT)
    , blue_pin(blue_identifier, OUTPUT)
{
    red_id = red_identifier;
    green_id = green_identifier;
    blue_id = blue_identifier;
}

(为了保持一致性,您可能还想将 red_idgreen_idblue_id 的初始化移到初始化列表中,但这不是必需的)

您已在 DigitalRGBPin() 构造函数中将 red_pingreen_pinblue_pin 声明为 局部变量 。因此,编译器错误是正确的 - 它们不在 initialize_rgb_pin()(或 DigitalRGBPin 的任何其他方法)访问的范围内。

您需要让他们成为 DigitalRGBPin class 的成员(就像您在 DigitalGPIOPin [= class、red_idgreen_idblue_id DigitalRGBPin class).

但是,您将不得不使用 DigitalRGBPin() 构造函数的 member initialization list to initialize them 1, since DigitalGPIOPin doesn't have a default constructor 定义。

1:在可行的情况下,您应该养成对所有 classes 使用成员初始化列表的习惯。

试试这个:

GPIOPin.hpp

class DigitalGPIOPin
{
public:
    int id;  // Pin identifier
    int io;  // INPUT or OUTPUT
    DigitalGPIOPin(int identifier, int io_type);
    void initialize_pin();
};
// -----------------------------------------------------------------
    
class DigitalRGBPin
{
public:
    int red_id, green_id, blue_id;
    DigitalGPIOPin red_pin, green_pin, blue_pin;
    DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
    void initialize_rgb_pin();
};
// =================================================================
// =================================================================

GPIOPin.cpp

DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type) :
    id(identifier),
    io(io_type)
{
}

void DigitalGPIOPin::initialize_pin()
{
    if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
        pinMode(id, io);
    }
    else {
        Serial.println("Pin mode not recognized");
    }
}
// -----------------------------------------------------------------
    
DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier) :
    red_id(red_identifier),
    green_id(green_identifier),
    blue_id(blue_identifier),
    red_pin(red_identifier, OUTPUT),
    green_pin(green_identifier, OUTPUT),
    blue_pin(blue_identifier, OUTPUT)
{
}
// -----------------------------------------------------------------

void DigitalRGBPin::initialize_rgb_pin()
{
    red_pin.initialize_pin();
    green_pin.initialize_pin();
    blue_pin.initialize_pin();
}

附带说明一下,DigitalRGBPin class 的 red_idgreen_idblue_id 成员是多余的,因此可以(和应该) 被删除以支持在需要时使用 red_pin.idgreen_pin.idblue_pin.id,例如:

GPIOPin.hpp

class DigitalGPIOPin
{
public:
    int id;  // Pin identifier
    int io;  // INPUT or OUTPUT
    DigitalGPIOPin(int identifier, int io_type);
    void initialize_pin();
};
// -----------------------------------------------------------------
    
class DigitalRGBPin
{
public:
    DigitalGPIOPin red_pin, green_pin, blue_pin;
    DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
    void initialize_rgb_pin();
};
// =================================================================
// =================================================================

GPIOPin.cpp

DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type) :
    id(identifier),
    io(io_type)
{
}

void DigitalGPIOPin::initialize_pin()
{
    if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
        pinMode(id, io);
    }
    else {
        Serial.println("Pin mode not recognized");
    }
}
// -----------------------------------------------------------------
    
DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier) :
    red_pin(red_identifier, OUTPUT),
    green_pin(green_identifier, OUTPUT),
    blue_pin(blue_identifier, OUTPUT)
{
}
// -----------------------------------------------------------------

void DigitalRGBPin::initialize_rgb_pin()
{
    red_pin.initialize_pin();
    green_pin.initialize_pin();
    blue_pin.initialize_pin();
}