为何会出现‘非类类型对象请求成员’错误?附有限自动机代码
解析C++报错:“在非类类型的对象中请求成员‘...’”的原因及代码问题分析
嘿,这个报错我太熟了!咱们先从通用原因说起,再结合你给的有限自动机代码来拆解问题。
一、报错的核心原因
这个错误本质就是:你尝试用.运算符去访问一个根本不是类/结构体实例的东西的成员。常见触发场景有这几种:
- 把对象指针当成普通对象用了:比如你创建了
automat_finit*类型的指针,却用.而不是->去调用成员函数/访问成员变量 - 变量类型声明乌龙:比如你本来想声明一个类对象,结果写成了类似
automat_finit my_automat();(这会被编译器当成函数声明,而不是对象实例化) - 内存破坏导致对象失效:比如越界写内存,把类对象的内存覆盖成了其他类型的数据,后续访问时编译器就会认为它不是类类型
二、结合你的代码分析可能的问题
先看你给出的automat_finit类代码,有几个明显的问题可能间接或直接导致这个报错:
1. 构造函数中关键成员变量未初始化
你的构造函数里,分配F数组和Sigma数组时用到了CxF和CxSigma,但这两个变量完全没有从文件中读取值!代码里只写了f >> CxQ;,却跳过了读取CxF(终态数量)、CxSigma(字母表大小)这些核心参数。
未初始化的成员变量是随机垃圾值,用它来分配数组会直接导致内存越界,破坏程序的内存结构——严重的话,甚至会把类对象本身的内存覆盖,导致后续访问对象成员时,编译器误以为它不是类类型,从而抛出这个错误。
2. 类对象调用时的常见误用(最可能直接触发报错)
假设你在主函数或其他地方使用这个类时,写成了这样:
// 创建了一个类指针 automat_finit* my_auto = new automat_finit(); // 错误:用了.而不是->访问成员函数 my_auto.tranzitie(0, 'a');
这种情况下,my_auto是指针类型(不是类实例),你用.去访问tranzitie成员,就会直接触发“在非类类型的对象中请求成员‘tranzitie’”的错误。正确的写法应该是用->:
my_auto->tranzitie(0, 'a');
另外还有个容易踩的坑:如果你把对象实例化写成了函数声明:
// 错误:这是声明了一个返回automat_finit的函数,不是创建对象 automat_finit my_auto(); // 调用成员时就会报错,因为my_auto是函数类型,不是类对象 my_auto.tranzitie(0, 'a');
正确的实例化应该是:
automat_finit my_auto;
三、修复代码的建议
- 先补全构造函数的成员变量初始化:在分配数组前,一定要从文件中读取所有必要的参数,比如:
automat_finit() { ifstream f("automatfinit.in"); SC = 0; // 按文件存储顺序读取所有配置参数 f >> CxQ >> CxF >> CxSigma >> CxTranzitii >> q0; F = new int[CxF]; for(int i = 0; i < CxF; i++) f >> F[i]; Sigma = new char[CxSigma]; for(int i = 0; i < CxSigma; i++) f >> Sigma[i]; // 初始化转移函数数组G G = new delta[CxTranzitii]; for(int i = 0; i < CxTranzitii; i++) { f >> G[i].a1 >> G[i].c >> G[i].a2; } f.close(); } - 检查类对象的使用方式:确保普通对象用
.访问成员,指针对象用->访问,避免把对象实例化写成函数声明。
内容的提问来源于stack exchange,提问作者user8113290
相关产品推荐
相关产品推荐

