C++嵌套类对象正确用法及Dmx无slider成员报错解决
问题原因
你的代码同时存在4个问题,'class Dmx' has no member named 'slider'报错由第4个问题直接导致:
- 构造函数不匹配:
Dmx类只定义了无参构造函数,但你在main中初始化Dmx数组时给每个元素传入了int类型参数,没有对应可调用的构造函数。
- 构造函数不匹配:
- 嵌套类构造函数不匹配:
Dmx::touchSlider类也只定义了无参构造,但你初始化slider数组时直接传入int参数,同样没有对应构造函数。
- 嵌套类构造函数不匹配:
- 类外实现成员函数漏写返回值:你在main.cpp中实现
printChannel和channelDisplay时,没有写返回值类型void,不符合C++语法。
- 类外实现成员函数漏写返回值:你在main.cpp中实现
- 混淆了嵌套类类型和类成员:你在
Dmx类中只是前置声明了嵌套类touchSlider这个类型,并没有在Dmx类内部定义touchSlider类型的成员变量。你在全局作用域定义的Dmx::touchSlider slider[10]是全局对象,不属于Dmx类的成员,如果你在代码中写了类似dmx[i].slider的写法试图通过Dmx实例访问slider,就会触发你看到的报错。
- 混淆了嵌套类类型和类成员:你在
C++嵌套类的正确使用规则
- 嵌套类本质是定义在外层类作用域下的独立类型,它的类型名受外层类命名空间限制,但不会自动成为外层类的成员变量,需要手动在外层类中声明对应类型的成员(或在全局/其他作用域定义该类型的对象)。
- 前置声明的嵌套类属于不完整类型,只能用来定义指针、引用,不能直接实例化作为外层类的对象成员;如果要在外层类中持有嵌套类的实例对象,必须在定义外层类之前让编译器看到嵌套类的完整定义。
- 嵌套类对外层类的私有、保护成员没有特殊访问权限,和普通类遵守一样的访问控制规则。
修正方案
根据你的代码结构,有两种常见修正方向,可根据需求选择:
方案1:slider作为全局对象使用(和你当前写法意图一致)
如果你本来就打算让slider是全局数组,不需要每个Dmx对象持有自己的slider,只需要修正构造函数、函数返回值即可,不需要修改Dmx类的结构:
- 给Dmx添加带int参数的构造函数,给touchSlider添加带int参数的构造函数
- 类外实现成员函数时补上
void返回值 - 不要通过Dmx实例访问slider,直接用全局的slider数组即可
修正后的各文件代码:dmx.h
// dmx.h #ifndef dmx_h #define dmx_h class Dmx { public: int id; // 存储传入的设备编号 Dmx() {} Dmx(int dmxId): id(dmxId) {} // 新增带参构造 void channelDisplay(); // 只保留声明,实现放cpp文件 class touchSlider; }; #endif
touchSlider.h
// touchSlider.h #ifndef touchSlider_h #define touchSlider_h #include "dmx.h" class Dmx::touchSlider{ private: int pos; // 存储传入的滑块坐标 public: touchSlider() {} touchSlider(int sliderPos): pos(sliderPos) {} // 新增带参构造 void printChannel(); }; #endif
main.cpp
// main.cpp #include "dmx.h" #include "touchSlider.h" Dmx dmx[10] = {Dmx(1), Dmx(2),Dmx(3), Dmx(4), Dmx(5), Dmx(6), Dmx(7), Dmx(8), Dmx(9), Dmx(10)}; Dmx::touchSlider slider[10] = {50,130,210,290,370,50,130,210,290,370}; // 实现成员函数,补上void返回值 void Dmx::touchSlider::printChannel() { // 自定义业务逻辑 } void Dmx::channelDisplay() { // 自定义业务逻辑 } int main() { // 直接访问全局对象即可,不要写dmx[0].slider这类访问方式 slider[0].printChannel(); dmx[0].channelDisplay(); return 0; }
方案2:每个Dmx对象持有自己的touchSlider成员
如果你是想让每个Dmx对象内部自带一个touchSlider实例,就需要在Dmx类中添加对应的成员变量。注意因为你把touchSlider的定义放在单独的头文件,Dmx类里只能用指针持有touchSlider(受不完整类型限制),如果要直接持有对象,需要把touchSlider的定义挪到Dmx类内部。
指针持有的写法示例:
修改dmx.h添加成员指针:
// dmx.h #ifndef dmx_h #define dmx_h class Dmx { public: int id; class touchSlider* slider; // 前置声明类型只能定义指针 Dmx() {} Dmx(int dmxId, int sliderPos); // 构造函数声明 void channelDisplay(); ~Dmx(); // 析构函数释放指针内存 class touchSlider; }; #endif
后续在构造函数中初始化slider指针,访问时就可以使用dmx[i].slider的写法。
内容的提问来源于stack exchange,提问作者LastHerd
相关产品推荐
相关产品推荐

