首页 > 解决方案 > 如何在 B 类的构造函数中实例化 C++ 类 A,使其对象可用于成员函数

问题描述

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

我创建了一个名为DigitalGPIOPin. 我还有另一个名为DigitalRGBPin的类,它需要DigitalGPIOPin在构造函数中实例化该类的 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

标签: c++arduinoinner-classes

解决方案


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

您需要让他们成为DigitalRGBPin班级的成员(就像您在班级中为 and 所做的那样,以及idio班级中DigitalGPIOPin为,所做的那样)。red_idgreen_idblue_idDigitalRGBPin

但是,您必须使用DigitalRGBPin()构造函数的成员初始化列表来初始化它们1,因为DigitalGPIOPin没有定义默认构造函数。

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

试试这个:

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();
}

在旁注中,类的red_id,green_idblue_id成员DigitalRGBPin是多余的,因此可以(并且应该)删除以支持使用red_pin.id,green_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();
}

推荐阅读