在另一个 objectB 中创建 objectA 时,objectA 是不是是 objectS 的本地对象,并且 objectS 是不是存在于对象实例化之外?

Posted

技术标签:

【中文标题】在另一个 objectB 中创建 objectA 时,objectA 是不是是 objectS 的本地对象,并且 objectS 是不是存在于对象实例化之外?【英文标题】:When creating an objectA inside another objectB, is objectA local to objectB and will objectA exist beyond objectB's instantiation?在另一个 objectB 中创建 objectA 时,objectA 是否是 objectS 的本地对象,并且 objectS 是否存在于对象实例化之外? 【发布时间】:2019-07-06 22:58:23 【问题描述】:

我的目标是创建两个类LEDPWM,目的是让每个LED 对象创建一个本地PWM 对象来控制亮度。这个想法是用户可以创建一个LED对象而不必设置PWM对象,同时保留单独创建PWM对象的选项用于电机速度控制等。

当我在LED 对象中实例化PWM 对象时,问题就来了。代码编译没有错误;然而,结果就像PWM 对象在LED 对象的构造函数完成后立即消失。 (当我触发相应的任务时,不会发生与 PWM 模块相关的任何事件。具体来说,pwm.stoppwm.start 函数使用一个空的 while 循环来等待特定事件,这些事件在执行任务时发出信号完成,并且当循环完成事件发生时,循环快捷方式会自动启动一个任务。当触发相应的任务时,这些事件都不会发生。数据手册警告:“注意,必须先启用外设,然后才能执行任务和事件使用过。”这让我相信pwm.enable() 没有运行。)

ohlemacher 这么说 constructors inside constructors:

“...它只是没有做你想做的事。内部构造函数将构造一个临时本地对象,一旦外部构造函数返回,该对象就会被删除。”

有没有更好的方法在创建 LED 对象时自动生成 PWM 对象?是否可以在不使 PWM 对象成为 LED 对象的成员的情况下做我想做的事情?

pwm.h

#ifndef rav_nrf52840_pwm_h
#define rav_nrf52840_pwm_h

#include "rav_nrf52840_baseConst.h"

typedef enum DIV1,DIV2,DIV4,DIV8,DIV16,DIV32,DIV64,DIV128 prescaler;
typedef enum PWM0,PWM1,PWM2,PWM3 pwmModule;
typedef enum COMMON,GROUPED,INDIVIDUAL,WAVEFORM decoderLoad;

class PWM 

private:

    unsigned int base_address;

    void enable_pwm (bool en);

    bool start_pwm (void);

    void stop_pwm (void);

public:

    PWM ();

    PWM (pwmModule module, bool looping, bool mode, int count, prescaler scale);

    void init (decoderLoad load, bool decoder_mode, int loop_count);

    void sequence (int seq_number, unsigned int *pointer, int count, int refresh, int enddelay);

    void pinSelect (int channel, int port, int pin, bool disconnect);

    void enable (void);

    void disable (void);

    bool start (void);

    void stop (void);
;

#endif

pwm.cpp

#include "rav_nrf52840_pwm.h"
#include <cstdint>

PWM::PWM ()
    #ifndef rav_nrf52840_pwm_pwm3
    #define rav_nrf52840_pwm_pwm3
    pwmModule module = PWM3;
    #else
    #ifndef rav_nrf52840_pwm_pwm2
    #define rav_nrf52840_pwm_pwm2
    pwmModule module = PWM2;
    #else
    #ifndef rav_nrf52840_pwm_pwm1
    #define rav_nrf52840_pwm_pwm1
    pwmModule module = PWM1;
    #else
    #ifndef rav_nrf52840_pwm_pwm0
    #define rav_nrf52840_pwm_pwm0
    pwmModule module = PWM0;
    #endif
    #endif
    #endif
    #endif

    bool looping = true;
    bool mode = 0;
    int count = 0x7FFF;
    prescaler scale = DIV4;
    switch (module)

        default:
            ;
        break;

        case PWM0:
            base_address = BASE_ADDRESS_PWM0;
        break;

        case PWM1:
            base_address = BASE_ADDRESS_PWM1;
        break;

        case PWM2:
            base_address = BASE_ADDRESS_PWM2;
        break;

        case PWM3:
            base_address = BASE_ADDRESS_PWM3;
        break;
    
    unsigned int * pwm_mode_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PWM_MODE);
    unsigned int * countertop_reg = (unsigned int *)(base_address + REGISTER_OFFSET_COUNTERTOP);
    unsigned int * prescaler_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PRESCALER);
    unsigned int * shortcut_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SHORTS);
    *pwm_mode_reg = mode;
    *countertop_reg = count;
    *prescaler_reg = scale;
    if (looping)
        *shortcut_reg = 0x04;  //  Enable looping
    


PWM::PWM (pwmModule module, bool looping, bool mode, int count, prescaler scale)
    switch (module)

        default:
            ;
        break;

        case PWM0:
            base_address = BASE_ADDRESS_PWM0;
        break;

        case PWM1:
            base_address = BASE_ADDRESS_PWM1;
        break;

        case PWM2:
            base_address = BASE_ADDRESS_PWM2;
        break;

        case PWM3:
            base_address = BASE_ADDRESS_PWM3;
        break;
    
    unsigned int * pwm_mode_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PWM_MODE);
    unsigned int * countertop_reg = (unsigned int *)(base_address + REGISTER_OFFSET_COUNTERTOP);
    unsigned int * prescaler_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PRESCALER);
    unsigned int * shortcut_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SHORTS);
    *pwm_mode_reg = mode;
    *countertop_reg = count;
    *prescaler_reg = scale;
    if (looping)
        *shortcut_reg = 0x04;  //  Enable looping
    






// PRIVATE

void PWM::enable_pwm (bool en)
    unsigned int * pwm_enable_reg = (unsigned int *)(base_address + REGISTER_OFFSET_ENABLE);
    *pwm_enable_reg = en;


bool PWM::start_pwm (void)
    unsigned int * start_seq0_task = (unsigned int *)(base_address + TASK_OFFSET_SEQSTART_0);
    volatile unsigned int * seq0_started_event = (unsigned int *)(base_address + EVENT_OFFSET_SEQSTARTED_0);
    *start_seq0_task = true;
    while(!*seq0_started_event)
    *seq0_started_event = false;
    return 1;


void PWM::stop_pwm (void)
    unsigned int * pwm_stop_task = (unsigned int *)(base_address + TASK_OFFSET_PWM_STOP);
    volatile unsigned int * pwm_stopped_event = (unsigned int *)(base_address + EVENT_OFFSET_STOPPED);
    *pwm_stop_task = true;
    while(!*pwm_stopped_event)
    *pwm_stopped_event = false;






// PUBLIC

void PWM::init (decoderLoad load, bool decoder_mode, int loop_count)
    unsigned int * decoder_reg = (unsigned int *)(base_address + REGISTER_OFFSET_DECODER);
    unsigned int * loop_reg = (unsigned int *)(base_address + REGISTER_OFFSET_LOOP);
    *decoder_reg = load;
    if (decoder_mode)
        *decoder_reg |= 0x100;
    
    *loop_reg = loop_count;


void PWM::sequence (int seq_number, unsigned int *pointer, int count, int refresh, int enddelay)
    unsigned int * seq_pointer_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_PTR + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_count_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_CNT + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_refresh_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_REFRESH + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_enddelay_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_ENDDELAY + (MODIFIER_SEQ * seq_number));
    *seq_pointer_reg = reinterpret_cast<std::uintptr_t>(pointer);
    *seq_count_reg = count;
    *seq_refresh_reg = refresh;
    *seq_enddelay_reg = enddelay;


void PWM::pinSelect (int channel, int port, int pin, bool disconnect)
    unsigned int * pin_select_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PSEL_OUT_0 + (MODIFIER_PSEL_OUT * channel));
    *pin_select_reg = ((disconnect << 31) | (port << 5) | pin);


void PWM::enable (void)
    enable_pwm(true);


void PWM::disable (void)
    enable_pwm(false);


bool PWM::start (void)
    bool pwm_seq_started = start_pwm();
    return pwm_seq_started;


void PWM::stop (void)
    stop_pwm();

led.h

#ifndef rav_nrf52840_led_h
#define rav_nrf52840_led_h

#include "rav_nrf52840_macros.h"
#include "rav_nrf52840_pwm.h"

typedef enum RED = 1,GREEN = 2,YELLOW = 3,BLUE = 4,MAGENTA = 5,CYAN = 6,WHITE = 7 ledState;

class LED 

private:

    PWM pwm;

    bool pwm_sequence_started_flag;

    bool LED_activeLow_flag;

    bool LED_RGB_flag;

    int  LED_portNumber[3];

    int  LED_pinNumber[3];

    int  LED_color;

    int  LED_intensity;

    unsigned int sequence_0[4];

public:

    LED (bool activeLow,int portNumber[3],int pinNumber[3]);  //  Use this format for RGB LEDs. Port and pin numbers must be listed in order: red, green, then blue.

    LED (bool activeLow,int portNumber,int pinNumber);  //  Use this format for single color LEDs

    void on (ledState color, int brightness);  //  Do not use this format with single color LEDs. Valid options for brightness are 0 - 100(%)

    void off (void);
;

#endif

led.cpp

#include "rav_nrf52840_led.h"

LED::LED (bool activeLow,int portNumber[3],int pinNumber[3]) : pwm()
    LED_RGB_flag = true;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber[0];
    LED_portNumber[1] = portNumber[1];
    LED_portNumber[2] = portNumber[2];
    LED_pinNumber[0] = pinNumber[0];
    LED_pinNumber[1] = pinNumber[1];
    LED_pinNumber[2] = pinNumber[2];
    pwm.init(INDIVIDUAL,0,0xFFFF);
    pwm.sequence(0,sequence_0,4,0,0);
    pwm.pinSelect(0,LED_portNumber[0],LED_pinNumber[0],false);
    pwm.pinSelect(1,LED_portNumber[1],LED_pinNumber[1],false);
    pwm.pinSelect(2,LED_portNumber[2],LED_pinNumber[2],false);
    pwm.enable();


LED::LED (bool activeLow,int portNumber,int pinNumber) : pwm()
    LED_RGB_flag = false;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber;
    LED_pinNumber[0] = pinNumber;
    pwm.init(INDIVIDUAL,0,0xFFFF);
    pwm.sequence(0,sequence_0,4,0,0);
    pwm.pinSelect(0,LED_portNumber[0],LED_pinNumber[0],false);
    pwm.enable();






// PRIVATE

int  LED_color = RED;  //  Default value for LED_color is RED.
int  LED_intensity = 0xFFFF;  //  Default value for LED_intensity is 0xFFFF.





// PUBLIC

void LED::on (ledState color, int brightness)
    LED_intensity = brightness;//(scale(brightness,0,100,0x8000,0xFFFF));
    if (pwm_sequence_started_flag)
        pwm.stop();
        pwm_sequence_started_flag = false;
    
    if (LED_RGB_flag)
        LED_color = color;
        if (brightness >= 0xFFFF)//100)
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 0:1) : writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 0:1) : writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 1:0);
        
        else
            sequence_0[0] = LED_intensity;
            sequence_0[1] = LED_intensity;
            sequence_0[2] = LED_intensity;
            pwm_sequence_started_flag = pwm.start();
        
    
    else
        if (brightness >= 100)
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
        
    


void LED::off (void)
    if (LED_RGB_flag)
        LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],1) : writePin(LED_portNumber[1],LED_pinNumber[1],0);
        LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],1) : writePin(LED_portNumber[2],LED_pinNumber[2],0);
    
    LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],1) : writePin(LED_portNumber[0],LED_pinNumber[0],0);

ma​​in.cpp

#include "rav_nrf52840_base.h"
#include "rav_nrf52840_led.h"


int main(void)  //  TX

    setupClock (HF_64MHz_XTAL, START);
    setupClock (LF_32_768kHz_XTAL, START);

    setupPin (0, 3,INPUT);
    pullPin  (0, 3,PULLUP);
    setupPin (0,18,INPUT);  //  External (? Ohm) pullup resistor.
    setupPin (0,22,OUTPUT);
    writePin (0,22,HIGH);
    setupPin (0,23,OUTPUT);
    writePin (0,23,HIGH);
    setupPin (0,24,OUTPUT);
    writePin (0,24,HIGH);

    int my_led_ports[3] = 0,0,0;
    int my_led_pins[3] = 23,22,24;  //  RED, GREEN, BLUE
    LED led(true,my_led_ports,my_led_pins);


    for(;;)
        if (readPin(0,3))
            ;
        
        else
            led.on(RED,0xFFFF);
        
        if (readPin(0,18))
            ;
        
        else
            led.on(RED,0xF000);
        
    
    return -1;


为了比较,这里是一个旧版本的代码(没有LEDPWM 成员)。 pwm.hpwm.cpp文件与新版本相同。

led.h -- 旧(工作)版本

#ifndef rav_nrf52840_led_h
#define rav_nrf52840_led_h

#include "rav_nrf52840_macros.h"

typedef enum RED = 1,GREEN = 2,YELLOW = 3,BLUE = 4,MAGENTA = 5,CYAN = 6,WHITE = 7 ledState;

class LED 

private:

    bool LED_activeLow_flag;

    bool LED_RGB_flag;

    int  LED_portNumber[3];

    int  LED_pinNumber[3];

    int  LED_color;

    int  LED_intensity;

public:

    LED (bool activeLow,int portNumber[3],int pinNumber[3]);  //  Use this format for RGB LEDs. Port and pin numbers must be listed in order: red, green, then blue.

    LED (bool activeLow,int portNumber,int pinNumber);  //  Use this format for single color LEDs

    void on (ledState color, int brightness);  //  Do not use this format with single color LEDs. Valid options for brightness are 0 - 100(%)

    void off (void);
;

#endif

led.cpp -- 旧(工作)版本

#include "rav_nrf52840_led.h"

LED::LED (bool activeLow,int portNumber[3],int pinNumber[3])
    LED_RGB_flag = true;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber[0];
    LED_portNumber[1] = portNumber[1];
    LED_portNumber[2] = portNumber[2];
    LED_pinNumber[0] = pinNumber[0];
    LED_pinNumber[1] = pinNumber[1];
    LED_pinNumber[2] = pinNumber[2];


LED::LED (bool activeLow,int portNumber,int pinNumber)
    LED_RGB_flag = false;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber;
    LED_pinNumber[0] = pinNumber;






// PRIVATE

bool LED_activeLow_flag;
bool LED_RGB_flag;
int  LED_portNumber[3];
int  LED_pinNumber[3];
int  LED_color = RED;  //  Default value is RED.
int  LED_intensity = 0xFFFF;  //  Default value is 0xFFFF.





// PUBLIC

void LED::on (ledState color, int brightness)
    LED_intensity = brightness;//(scale(brightness,0,100,0x8000,0xFFFF));
    if (LED_RGB_flag)
        LED_color = color;
        if (brightness >= 0xFFFF)//100)
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 0:1) : writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 0:1) : writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 1:0);
        
    
    else
        if (brightness >= 0xFFFF)//100)
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
        
    


void LED::off (void)
    if (LED_RGB_flag)
        LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],1) : writePin(LED_portNumber[1],LED_pinNumber[1],0);
        LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],1) : writePin(LED_portNumber[2],LED_pinNumber[2],0);
    
    LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],1) : writePin(LED_portNumber[0],LED_pinNumber[0],0);

ma​​in.cpp -- 旧(工作)版本

#include "rav_nrf52840_base.h"
#include "rav_nrf52840_led.h"
#include "rav_nrf52840_pwm.h"


int main(void)  //  TX

    setupClock (HF_64MHz_XTAL, START);
    setupClock (LF_32_768kHz_XTAL, START);

    setupPin (0, 3,INPUT);
    pullPin  (0, 3,PULLUP);
    setupPin (0,18,INPUT);  //  External (? Ohm) pullup resistor.
    setupPin (0,22,OUTPUT);
    writePin (0,22,HIGH);
    setupPin (0,23,OUTPUT);
    writePin (0,23,HIGH);
    setupPin (0,24,OUTPUT);
    writePin (0,24,HIGH);

    int my_led_ports[3] = 0,0,0;
    int my_led_pins[3] = 23,22,24;  //  RED, GREEN, BLUE
    LED led(true,my_led_ports,my_led_pins);

    bool pwm_sequence_started_flag = 0;
    int  LED_portNumber[3] = 0,0,0;
    int  LED_pinNumber[3] = 23,22,24;
    unsigned int sequence_0[4];
    PWM pwm(PWM0,true,0,0x7FFF,DIV4);
    pwm.init(INDIVIDUAL,0,0xFFFF);
    pwm.sequence(0,sequence_0,4,0,0);
    pwm.pinSelect(0,LED_portNumber[0],LED_pinNumber[0],false);
//  pwm.pinSelect(1,LED_portNumber[1],LED_pinNumber[1],false);
//  pwm.pinSelect(2,LED_portNumber[2],LED_pinNumber[2],false);
    pwm.enable();


    for(;;)
        if (readPin(0,3))
            ;
        
        else
            if (pwm_sequence_started_flag)
                pwm.stop();
                pwm_sequence_started_flag = false;
            
            led.on(RED,0xFFFF);
        
        if (readPin(0,18))
            ;
        
        else
            led.off();
            if (pwm_sequence_started_flag)
                pwm.stop();
                pwm_sequence_started_flag = false;
            
            int LED_intensity = 0xF000;
            sequence_0[0] = LED_intensity;
            sequence_0[1] = LED_intensity;
            sequence_0[2] = LED_intensity;
            pwm_sequence_started_flag = pwm.start();
        
    
    return -1;

【问题讨论】:

由于PWM是LED的成员,所以只有在LED消失时才会消失,而不是在构造函数完成时消失。 这就是我最初的想法。我一定误解了ohlemacher。那么,我上面的代码中的错误是什么?据我了解,PWM 对象应该在LED 对象的实例化列表运行时创建。我可以验证LED 构造函数中的pwm.enable() 函数没有运行,或者看不到它的效果。 @KCEngel 您如何验证pwm.enable() 没有运行?也就是说,你的症状是什么?与您的预期结果相比,您的实际结果是什么?你做了什么debugging? @JaMiT 这更像是一个有根据的猜测。我正在使用没有板载调试器的 NRF52840 USB 加密狗。在他们的论坛上:The short answer is: It is not possible to debug on the nRF52840 dongle.我应该买了开发工具包。 @JaMiT 我观察到,当我触发相应的任务时,没有发生与 PWM 模块相关的事件。具体来说,pwm.stop 和 pwm.start 函数使用空的 while 循环来等待指示任务完成时发出信号的特定事件,并且循环快捷方式会在 loop complete 事件发生时自动启动任务。当适当的任务被触发时,这些事件都不会发生。数据手册警告:“请注意,必须先启用外设,然后才能使用任务和事件。”这让我相信 pwm.enable() 没有运行。 【参考方案1】:

新旧代码之间存在一些逻辑差异。最有可能的是,其中之一就是罪魁祸首。此外,还有一些你可以摆脱的无用代码。最后,您似乎误解了 ohlemacher 对其他问题的回答。


我看到的新旧版本之间最显着的逻辑区别是新版本默认构造PWM 对象,而旧版本使用参数化构造函数。您可以通过使用旧的工作版本并将PWM pwm(PWM0,true,0,0x7FFF,DIV4); 更改为PWM pwm; 来查看这是否是您的问题的原因。您可以通过更改两个LED 构造函数来为包含的PWM 对象指定参数来修复新版本;将: pwm() 更改为: pwm(PWM0,true,0,0x7FFF,DIV4)

另一个逻辑上的区别是旧版本调用led.off(),而新版本调用led.on(RED,0xF000);。在这里协调逻辑并不像更改对off() 的调用那么简单,因为LED::off() 函数没有更新。要检查这种差异,请注释掉旧 LED::off() 函数中的所有代码。修复新版本有点复杂。我现在将跳过如何执行此操作,因为我怀疑PWM 构造函数的选择是真正的罪魁祸首。

其他逻辑差异似乎不太可能导致您的症状,但无论如何我都会列出它们。旧版本不会为通道 1 和 2 调用 PWM::pinSelect,而新版本会调用。旧版本将pwm_sequence_started_flag初始化为0(隐式转换为false),而新版本对此标志没有显式初始化。


led.cpp 的旧版本和新版本中,都有一个标记为“// PRIVATE”的部分没有任何作用。本节定义了一些与LED 类成员同名的(全局)变量。您的LED 成员函数不引用这些变量;当LED::on() 设置LED_intensity 时,它设置成员this-&gt;LED_intensity,而不是全局::LED_intensity。此外,您的其他源文件不太可能引用这些全局变量,因为它们未在led.h 中声明。删除这些未使用的声明。

虽然不是严格意义上的无用,但您也可以摆脱 void 的某些用法。在 C++(相对于 C)中,可以使用 bool start_pwm (); 而不是 bool start_pwm (void); 来声明不带参数的函数。跳过“void”意味着用于阅读代码的脑力减少了一点点,因此用于理解代码的脑力增加了一点点。 Smidgens 可以加起来。

使用typedef 为枚举命名,看起来也像是被引入C++ 的C 主义。尝试使用enum pwmModule PWM0,PWM1,PWM2,PWM3; 而不是typedef enum PWM0,PWM1,PWM2,PWM3 pwmModule;。同样,要阅读的代码更少。

关于简化代码,一行

LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);

是粗略的阅读。如果将最后一个参数的计算与对writePin() 的调用分开,则更容易看到发生了什么。逻辑上等价(假设参数是int):

int foo = readBit(LED_color,0) ? (LED_activeLow_flag ? 0 : 1) : (LED_activeLow_flag ? 1 : 0);
writePin(LED_portNumber[0], LED_pinNumber[0], foo);

这清楚地表明无论条件如何,都会调用writePin(),并且前两个参数也与条件无关。只有最后一个参数可以变化。


让我们继续ohlemacher's answer。声称“它只是不做你想做的事”是指在构造函数体中调用类的构造函数。也就是说,给定class A,写类似A::A(bool) A(); 。在构造函数体内创建一个对象,构造函数返回时自然会销毁。

此外,ohlemacher 回答的问题是关于调用与构造函数相同的类的构造函数(也称为 C++11 中引入的“委托构造函数”)。您关心的情况是调用数据成员的构造函数。对于数据成员,member initializer lists 自语言标准化以来一直可用。

【讨论】:

不错的收获。发现。不幸的是,它们似乎不是我问题的根源。无论我使用哪个构造函数,我都会得到相同的结果。我删除了全局变量,修复了 C-isms,并将该标志添加到初始化列表中,但没有任何乐趣。 我说得太早了。将pwm_sequence_started_flag 添加到初始化列表是我尝试的最后一件事,我不认为会是这样,但确实如此!感谢您的所有帮助!【参考方案2】:

最简单的方法是使用智能指针。让LED 对象包含std::shared_ptr&lt;PWM&gt; 对象,可以在构造函数或成员函数中使用std::make_shared 随时创建。这样,当LED 死亡时,您可以自动清理对象,并且您可以将PWM 对象复制到其他地方,这样当LED 被破坏时它仍然存在。

这样,您可以让任何类按需包含另一个类,并且仍然能够轻松清理。

【讨论】:

为什么引入动态分配比简单地将PWM 对象直接作为每个LED 对象中的字段更容易?

以上是关于在另一个 objectB 中创建 objectA 时,objectA 是不是是 objectS 的本地对象,并且 objectS 是不是存在于对象实例化之外?的主要内容,如果未能解决你的问题,请参考以下文章

ObjectA.Signal.connect(ObjectB.Slot) 不工作。我的理解正确吗?

如何根据相关对象集合的属性对 Core Data 结果进行排序?

使用 ARC 的 Objective-C 代表

Nullify 删除规则到底在做啥?

带有类型检查的Scala相等性?

编写高质量代码改善C#程序的157个建议——建议98:用params减少重复参数