【问题标题】:In C++ language, how do you create a new object which is a pointer to an array?在 C++ 语言中,如何创建一个指向数组的指针的新对象?
【发布时间】:2016-11-29 20:33:46
【问题描述】:

我正在使用以这种方式声明方法的第 3 方库:

void nexLoop(NexTouch *nex_listen_list[]);

如果是单个 .cpp 文件,这是可行的:

NexButton b0 = NexButton(0, 1, "b0");
NexTouch *nex_listen_list[] = 
{
    &b0,
    NULL
};
...
nexLoop(nex_listen_list);

完整的示例代码可以在这里看到:https://github.com/itead/ITEADLIB_Arduino_Nextion/blob/master/examples/CompText/CompText.ino

现在我将这个库合并到一个有单独的头文件和 c 文件的类中,这样:

MyNextion.h

#include "Nextion.h"

class MyNextion {
   public:
       MyNextion();
       void loop();
   private: 
       NexButton *b0;
       NexTouch *nex_listen_list[];
}

MyNextion.cpp

#include "MyNextion.h"

MyNextion::MyNextion() {
    b0 = new NexButton(0, 1, "b0");
    nex_listen_list = new ???
}

MyNextion::loop() {
    nexLoop(nex_listen_list); // ???
}

我一直在搞乱指针和地址运算符,但我找不到成功编译的正确组合。

我的问题是:你会在这里放什么:nex_listen_list = new ???;

另外,我不确定标题是否能很好地定义我的问题。如果您对标题有更好的想法,请更正。

谢谢!

【问题讨论】:

  • 这是什么语言?看起来不像 C。试图看起来像 C++,但它失败了。
  • 好吧,你可能是对的。实际上这是 C/C++ 的 Arduino 代码。
  • “一个新对象,它是一个指向数组的指针”?对我来说没有任何意义。
  • C/C++ ??那是什么语言?
  • 请随时编辑问题以使其更有意义。我不是以英语为母语的人。

标签: c++ class oop pointers


【解决方案1】:

您不应声明没有大小的成员数组。相反,您可以声明一个指向指针的指针:

class MyNextion {
   ...
   private: 
       NexButton *b0;
       NexTouch **nex_listen_list;
};

然后构造很简单:

nex_listen_list = new NexTouch*[10];
nex_listen_list[0] = b0;
....

也就是说,nex_listen_list 是指向NexTouch 对象的指针的动态数组。完成后不要忘记delete[]

delete[] nex_listen_list;

也就是说,如果数组的大小是恒定的,一个普通的数组就可以了:

       NexButton *b0;
       NexTouch *nex_listen_list[3];

如果没有,我宁愿使用std::vector。比如:

class MyNextion {
   ...
   private: 
       NexButton *b0;
       std::vector<NexTouch*> nex_listen_list;
};

然后不需要newdelete

nex_listen_list.push_back(b0);
nexLoop(nex_listen_list.data());

然后,您可以将b0 声明为完整对象,而不是指针:

class MyNextion {
   ...
   private: 
       NexButton b0;
       std::vector<NexTouch*> nex_listen_list;
};
...
nex_listen_list.push_back(&b0); //use the pointer!

没有new,所以没有delete,也没有泄漏。

【讨论】:

  • 这已经很有帮助了!我设法摆脱了很多编译器错误,但是我正面临着其他人。请参阅我更新的问题。感谢您的帮助!
  • 我建议展示智能指针的使用,而不是“裸”new/delete、C++11 和所有...
  • @papaiatis:你真的应该关闭这个问题并创建一个新问题。无论如何,您不能将指向成员的函数转换为指向函数的指针,它们可能看起来相同但非常不同!
  • @DevSolar:好吧,在这种情况下,您可能根本不需要动态对象。但我根本不知道使用的库,或者即使 OP 有可用的 C++11。毕竟是 Arduino ......
  • @rodrigo 当然,我正在为此打开一个单独的问题。再次感谢您!
【解决方案2】:

如果nex_listen_list 具有静态大小,则应按值保留:

// Interface
class MyNextion {
public:
   MyNextion() {}
   void loop();
private:
   NexButton b0{0, 1, "b0"};
   NexTouch *nex_listen_list[2] = {&b0, nullptr};
};

// Implementation
void MyNextion::loop() {
   nexLoop(nex_listen_list);
}

如果大小是可变的,您有两种选择。如果您不介意动态内存分配,请使用std::vector

// Interface
class MyNextion {
public:
   MyNextion() {}
   void loop();
   void foo();
private:
   NexButton b0{0, 1, "b0"};
   NexButton b1{0, 2, "b1"};
   std::vector<NexTouch *> nex_listen_list{&b0, nullptr};
   void append(NexTouch *t);
};

// Implementation
void MyNextion::append(NexTouch *t) {
   nex_listen_list.back() = t;
   nex_listen_list.push_back(nullptr);
}

void MyNextion::foo() {
   append(&b1);
}

void MyNextion::loop() {
   nexLoop(nex_listen_list.data());
}

或者,您可以预先分配一个固定大小的列表并避免动态内存分配:

lass MyNextion {
public:
   MyNextion() {}
   void loop();
   void foo();
private:
   void append(NexTouch *);
   NexButton b0{0, 1, "b0"};
   NexButton b1{0, 2, "b1"};
   std::array<NexTouch *, 10> nex_listen_list{{&b0, nullptr}};
   std::array<NexTouch *, 10>::iterator it_el =
         std::find(nex_listen_list.begin(), nex_listen_list.end(), nullptr);
};

// Implementation
void MyNextion::append(NexTouch *t) {
   *it_el++ = t;
   *it_el++ = nullptr;
}

void MyNextion::foo() {
   append(&b1);
}

void MyNextion::loop() {
   nexLoop(nex_listen_list.data());
}

你得到了一个相当强大的 C++ 编译器。您应该利用它为您编写代码。特别是,您应该让编译器为构造函数生成代码。

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 1970-01-01
    • 2020-03-26
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多