C++中使用const对象调用const成员函数时编译报错求助
解决const对象调用const成员函数的编译错误
咱们先来看你遇到的编译错误,核心问题出在这行代码上:
const Contmem obj;
错误根源
当你声明一个不带参数的const Contmem对象时,编译器会尝试调用无参的默认构造函数,但你的Contmem类已经显式定义了一个需要3个int参数的构造函数——根据C++的规则,一旦你自己定义了构造函数,编译器就不会再自动生成默认的无参构造函数了。
另外,你的类里还有const int constmem和const int constant这类const成员变量,它们的特性是必须在对象创建的那一刻就完成初始化,根本没法在构造函数体内赋值,所以哪怕你想写一个无参构造函数,也得在初始化列表里给这些const成员指定初始值。
解决方案
我们可以通过两种方式解决构造函数的问题,同时顺便修复printconst()函数里的一个小逻辑错误:
方案1:给现有构造函数加默认参数
修改头文件里的构造函数声明,给三个参数都加上默认值,这样它既能当带3个参数的构造函数用,也能当无参默认构造函数用,完美适配两种创建对象的场景:
// 头文件中的构造函数声明改成这样 Contmem(int a = 0, int b = 0, int c = 0);
方案2:单独定义默认构造函数
如果你不想给现有构造函数加默认参数,也可以单独写一个无参的默认构造函数,记得在初始化列表里给所有const成员赋值:
// 先在头文件里添加声明 Contmem(); // 然后在Contmem.cpp里实现 Contmem::Contmem() : mem(0), constmem(0), constant(0) { total = mem * constmem * constant; }
额外修复:printconst()函数的逻辑bug
你的printconst()函数里,return total;写在了std::cout语句前面,这会导致cout的内容永远不会被执行——函数一遇到return就直接返回了,后面的代码根本走不到。把顺序调过来就行:
int Contmem::printconst() const { std::cout << "This is the total variable " << total << std::endl; return total; }
修改后的完整可运行代码
Contmem.h
#ifndef CONTMEM_H #define CONTMEM_H class Contmem { public: // 用方案1的带默认参数构造函数 Contmem(int a = 0, int b = 0, int c = 0); int total; int mem; const int constmem; const int constant; int printconst() const; void print(); }; #endif // CONTMEM_H
Contmem.cpp
#include "Contmem.h" #include <iostream> Contmem::Contmem(int a, int b, int c) : mem(a), constmem(b), constant(c) { total = mem * constmem * constant; } void Contmem::print() { std::cout << "This is my variable member " << mem << " and this is my constmem member " << constmem << " with the constant member " << constant << std::endl; } int Contmem::printconst() const { std::cout << "This is the total variable " << total << std::endl; return total; }
main.cpp
#include <iostream> #include "Contmem.h" int main() { Contmem cont(3, 4, 5); cont.print(); const Contmem obj; // 现在可以正常编译运行了 obj.printconst(); }
最后再划个重点
- 只要你自己定义了类的构造函数,编译器就不会自动生成默认无参构造函数,需要手动提供
- const成员变量必须在构造函数的初始化列表里完成初始化,绝对不能在构造函数体内赋值
- 写函数的时候注意语句顺序,别让return把后面的代码给“跳过”了
内容的提问来源于stack exchange,提问作者enigmatic
相关产品推荐
相关产品推荐

