在类函数中初始化外部作用域变量
Initialize outer scope variable in class function
我是新手C++因为我来自C#背景。由于 https://docs.platformio.org/,我正在使用 vs 代码使用 c++ 创建一个 Arduino 项目。
以下代码有效并打开我的 LED 灯条:
主.cpp
#include <Arduino.h>
#include <LedStrip.h>
// pin where led strip is connected
#define LED_STIP_PIN 4
// number of leds in the strip
#define LED_STRIP_COUNT 7
// My wrapper class
LedStrip myLedStripWrapper;
void setup() {
// empty
}
void loop() {
myLedStripWrapper.setup(LED_STRIP_COUNT, LED_STIP_PIN);
// myLedStripWrapper.foo1(); // <<<HERE-1>>>
// wait forever
while (true) {
delay(1);
}
}
LedStrip.h
#include <Adafruit_NeoPixel.h>
class LedStrip
{
public:
Adafruit_NeoPixel strip;
void setup(uint16_t led_count, uint16_t pin)
{
// Declare our NeoPixel strip object:
Adafruit_NeoPixel a(led_count, pin, NEO_GRB + NEO_KHZ800);
strip = a;
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
foo1(); // <<<HERE-2>>> <------------------- calling foo1 from here turns on the led strip
}
// Color led strip blue
void foo1()
{
uint32_t color = strip.Color(0, 0, 100);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{ // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
// delay(100);
}
}
};
请注意,在代码中,我有标签<<<HERE-1>>>
和<<<HERE-2>>>
。我想从<<<HERE-1>>>
调用函数foo1
。为什么如果我取消注释<<<HERE-1>>>
并<<<HERE-2>>>
注释代码不起作用并且 LED 灯条无法打开?换句话说,我不想从类包装器中调用 foo1。我只是在那里称它为形式,因为它只有在我在那里称它为形式时才有效。
该类的作者犯了一个小学C++错误,没有正确遵守三法则。这意味着可以在不安全的情况下复制Adafruit_NeoPixel
对象。
void setup(uint16_t led_count, uint16_t pin)
{
// Declare our NeoPixel strip object:
Adafruit_NeoPixel a(led_count, pin, NEO_GRB + NEO_KHZ800);
strip = a; // copy here. Both a and strip point to a shared resource
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
} // a goes out of scope here and frees the shared resource in its
// destructor. Oops.
最简单的解决方法是在不需要复制的构造函数中初始化LedStrip
strip
。
为了确保不复制strip
,您必须防止复制LedStrip
或实现允许在不复制strip
的情况下复制LedStrip
的特殊成员函数。在下面的示例中,我将简单地防止复制。
如果需要复制,请考虑将Adafruit_NeoPixel strip;
替换为std::shared_ptr<Adafruit_NeoPixel> strip;
,以便复制指针,而不是复制时可能变成炸弹的对象。
class LedStrip
{
public:
Adafruit_NeoPixel strip; // you sure you want this public?
// adding constructor so we don't have to copy a Adafruit_NeoPixel object
LedStrip(uint16_t led_count, uint16_t pin):
strip(led_count, pin, NEO_GRB + NEO_KHZ800) // this is a member initializer list
// It allows us to construct strip
// without having to copy anything.
// more on that later
{
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
}
// preventing copying of LedStrip
LedStrip(const LedStrip& ) = delete;
LedStrip & operator=(const LedStrip& ) = delete;
// note if the compiler doesn't like the = delete, remove it, make
// the copy constructor and assignment operator private, and do not
// implement them
// Color led strip blue
void foo1()
{
uint32_t color = strip.Color(0, 0, 100);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{ // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
// delay(100);
}
}
private:
/* only needed if the = delete trick above doesn't work.
LedStrip(const LedStrip& );
LedStrip & operator=(const LedStrip& );
*/
};
然后
LedStrip myLedStripWrapper;
成为
LedStrip myLedStripWrapper(LED_STRIP_COUNT, LED_STIP_PIN);
和
myLedStripWrapper.setup(LED_STRIP_COUNT, LED_STIP_PIN);
从世界上消失,再也看不到了。
有关成员初始值设定项列表的文档。
有关std::shared_ptr
的文档
相关文章:
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 未在此作用域中声明的函数和变量 (C++)
- 如何在C++中访问作用域的变量输出?
- 不同块作用域中的 C++ 变量具有相同的地址
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- Tictactoe 游戏变量未在作用域中声明
- C++If语句变量作用域
- 即使在离开作用域后,如何访问在堆上分配的变量C++?
- C++ 在方程中使用变量;错误:表达式必须具有整数或无作用域枚举类型及其他
- 局部变量的作用域是块或函数
- 当变量在多个函数作用域中使用时,我应该在类 private 中声明该变量吗?
- C++11 外部作用域变量声明为 auto
- 是一个初始化为未确定值或未初始化的本地作用域变量
- 命名空间作用域变量的c++初始化
- c++双删除文件作用域变量,链接问题
- 线程局部全局作用域变量
- 嵌套while循环中的作用域变量
- 如何从函数内部修改作用域变量
- c++中不一致的文件作用域变量行为