首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在const class函数中更改类指针的值在某些编译器中会出现错误,但在其他编译器中不会出现错误

这个问题涉及到C++编程语言中的const成员函数和指针的相关知识。

在C++中,const成员函数是指在类中声明为const的成员函数,它们承诺不会修改类的成员变量。当我们在const成员函数中尝试修改类指针的值时,编译器会发出错误提示。

这是因为const成员函数默认情况下将类对象视为常量对象,而常量对象的成员变量是不可修改的。因此,如果我们在const成员函数中尝试修改类指针的值,就违反了const成员函数的约定,编译器会报错。

然而,不同的编译器对于这种情况的处理方式可能有所不同。有些编译器可能会在编译时发出错误,而另一些编译器可能会默默地忽略这个错误,导致程序在运行时出现未定义的行为。

为了避免这个问题,我们应该遵循const成员函数的约定,不在其中修改类指针的值。如果确实需要在const成员函数中修改指针的值,可以将指针声明为mutable,这样就可以在const成员函数中修改它的值了。

总结起来,const class函数中更改类指针的值在某些编译器中会出现错误,但在其他编译器中不会出现错误。为了避免这个问题,我们应该遵循const成员函数的约定,不在其中修改类指针的值,或者将指针声明为mutable。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

模板进阶:特化与编译链接全解析

**注意:**一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出 模板特化的出现是为了解决模板在处理某些特殊类型时可能遇到的问题。...// 例如日期类中的函数模板的使用,在使用指针比较的时候就会出现错误,这时候就需要进行模板特化 templateclass T> bool Less(T left, T right) { return...参数一致性:特化函数的参数列表必须与原模板函数保持一致,不能增加或减少参数,也不能更改参数的顺序或类型。 **注意:**推荐直接写一个函数实现特殊处理,编译器在处理的时候会优先调用更匹配的。...实现细节:在构造函数中接受了T1和T2类型的引用,并初始化类的成员变量。 成员变量:特化类中的成员变量是对传入对象的常量引用const T1&和const T2&,这确保了数据不会被意外修改。...防止修改传入的参数:特化版本中的Date* const& left和Date* const& right,通过使用const,函数保证不会修改传入的指针变量本身的值,即指针的指向保持不变。

17810

如何设计一个C++的类?

其实不标const也不会有任何问题,但是如果我们期望某个函数内不会修改任何成员变量时,应该把该成员函数标记为const,这样可以防止自己或者其它程序员误操作,当误更改了某些成员变量时,编译器会报错。...如果你期望在某个成员函数内不更改成员函数,而又没有标记为const,这时自己或者其他人在此函数内改动了某些成员变量,编译器对此没有任何提示,这就有可能产生潜在的bug。...函数传参无非就是传值还是传引用的选择问题: 参数需要在函数内修改,并在函数外使用修改后的值时:传引用 参数需要在函数内修改,但在函数外使用修改前的值时:传值 参数在函数内不会修改,参数类型如果为基础类型...(int等):传值 参数在函数内不会更改,参数类型如果为class类型:传const引用 类的声明和实现要分开写到不同文件中吗?...如果非内联函数在头文件中定义,多个源文件都引用此头文件时编译器就会报错。至于类的声明写到头文件还是源文件中,视情况而定,看下面这段代码,某些类的声明写到了头文件中,又有些类的声明写到了源文件中!

1.6K20
  • 二、从C语言到C++(二)

    然而,在C++中,直接将 NULL 定义为 (void*)0 可能会导致类型安全的问题,因为当你尝试将一个 void* 类型的值赋给一个非 void* 类型的指针时,编译器可能会发出警告或错误。...然而,C语言中的 const 并不提供运行时保护,也就是说,如果你在程序运行时通过某种方式(比如指针操作)绕过编译器的检查去修改 const 变量的值,编译器是无法阻止的。...const 成员函数:在C++中,你可以声明一个成员函数为 const,这意味着该函数不会修改其所属对象的任何成员变量(除非这些变量也被声明为 mutable)。这有助于维护类的封装性和数据完整性。...const 引用参数:在C++中,你可以将函数参数声明为 const 引用,这样可以确保在函数内部不会修改传入的参数。...以下是一些主要的区别: 作用域: 在C语言中,const变量默认具有文件作用域(除非在函数内部声明),并且如果在一个头文件中声明了const变量,那么在包含该头文件的多个源文件中会出现重复定义的错误

    7310

    Visual C++ 中的重大更改

    新版本中会引起这类问题的更改称为重大更改,通常,修改 C++ 语言标准、函数签名或内存中的对象布局时需要进行这种更改。     ...重大更改为,如果你之前使用的是具有相同签名的运算符 delete(以与 placement new 运算符对应),你将收到编译器错误(C2956,在使用 placement new 的点位置出现,因为在代码中的该位置...更改指针类型需要对使用联合字段的代码进行更改。 将代码更改为值将更改存储在联合中的数据,这会影响其他字段,因为联合类型中的字段共享相同的内存。 根据值的大小,它还可能更改联合的大小。 ...但在 Visual Studio 2015 中的 Visual C++ 中,不会调用构造函数和析构函数。 编译器会对关于此行为的更改发出警告。           ...这些无效的实例化通常不会导致编译器错误,这被称为 SFINAE(替换失败不是错误)原则。 现在,如果 SFINAE 要求编译器将类模板专用化进行实例化,则在此过程中发生的任何错误都是编译器错误。

    5.3K10

    Visual C++ 中的重大更改

    新版本中会引起这类问题的更改称为重大更改,通常,修改 C++ 语言标准、函数签名或内存中的对象布局时需要进行这种更改。     ...重大更改为,如果你之前使用的是具有相同签名的运算符 delete(以与 placement new 运算符对应),你将收到编译器错误(C2956,在使用 placement new 的点位置出现,因为在代码中的该位置...更改指针类型需要对使用联合字段的代码进行更改。 将代码更改为值将更改存储在联合中的数据,这会影响其他字段,因为联合类型中的字段共享相同的内存。 根据值的大小,它还可能更改联合的大小。 ...但在 Visual Studio 2015 中的 Visual C++ 中,不会调用构造函数和析构函数。 编译器会对关于此行为的更改发出警告。           ...这些无效的实例化通常不会导致编译器错误,这被称为 SFINAE(替换失败不是错误)原则。 现在,如果 SFINAE 要求编译器将类模板专用化进行实例化,则在此过程中发生的任何错误都是编译器错误。

    4.8K00

    学过 C++ 的你,不得不知的这 10 条细节!

    ---- 细节 02:尽可能使用 const const 的一件奇妙的事情是:它允许你告诉编译器和其他程序员某值应该保持不变。 1....data 如果关键词const出现在星号(*)左边,表示指针所指物是常量(不能改变 *p 的值); 如果关键词const出现在星号(*)右边,表示指针自身是常量(不能改变 p 的值); 如果关键词const...---- 细节 02 小结 - 请记住 将某些东西声明为 const 可帮助编译器探测出错误用法。const 可以被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。...---- 细节 03:确定对象被使用前先被初始化 内置类型初始化 如果你这么写: int x; 在某些语境下 x 保证被初始化为 0,但在其他语境中却不保证。...多态性质基类需声明 virtual 析构函数 如果在多态性质的基类,没有声明一个 virtual 析构函数,那么在 delete 基类指针对象的时候,只会调用基类的析构函数,而不会调用派生类的析构函数,

    75520

    C++11新关键字

    auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...5.constexpr 5.1简介 constexpr在C++11中用于申明常量表达式(const expression),可作用于函数返回值、函数参数、数据申明以及类的构造函数等。...(args)函数参数的数目 } 9.default和delete[8]^{[8]}[8] 9.1default 我们知道,C++98和C++03编译器在类中会隐式地产生四个函数:默认构造函数...9.2delete delete关键在C++11之前是对象释放运算符,但在C++11中,被赋予了新的功能,主要有如下几种作用。 (1)禁止编译器生成上面六种函数的默认版本。...如果断言表达式的值为 false ,那么编译器会出现一个包含指定字符串的错误,同时编译失败。如果为 true 那么没有任何影响。

    3.1K10

    C++11——引入的新关键字

    auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...(args)函数参数的数目 } 8.default和delete[8]^{[8]} 8.1default 我们知道,C++98和C++03编译器在类中会隐式地产生四个函数:默认构造函数...在 C++11 中,被称为 “特殊成员函数” 的还有两个:移动构造函数和移动赋值运算符函数。如果用户申明了上面六种函数,编译器则不会隐式产生。...8.2delete delete关键在C++11之前是对象释放运算符,但在C++11中,被赋予了新的功能,主要有如下几种作用: (1)禁止编译器生成上面六种函数的默认版本。...一个表达式可以被计算为 bool 或 string (字符串),如果这个表达式的值为 false ,那么编译器会出现一个包含特定字符串的错误,同时编译失败。如果为 true 那么没有任何影响。

    1.5K50

    CC++ const

    下面将从七个方面总结const的用法。 1.const位置 const位置较为灵活,一般来说,除了修饰一个类的成员函数外,const不会出现在一条语句的最后。...后者表示指针p本身的值不可修改,一旦p指向某个整型变量之后就不能指向其他的变量,即p是个指针常量。 (5)引用本身可以理解为指针常量,在引用前使用const没有意义。...但在某些情况下,const只能放在特定的位置,考查const配合二重指针的例子,代码如下: int main(int argc,char* argv[]) { //const配合二重指针...(4)非只读对象(如a1)调用某个函数时,先寻找它的非const函数版本,如果没有找到,再调用它的const函数版本。而常对象(a2),只能调用类中定义的常函数,否则出现编译错误。...3.const修饰函数的参数和函数的返回值 在定义函数时常用到const,主要用来修饰参数和返回值。其目的是让编译器为程序员做变量的只读性检查,以使程序更加健壮。

    87710

    《Effective Modren C++》 进阶学习(上)

    两者未明确被指名是指针类型,在使用时可能会带来类型转换等问题。而nullptr为明确的空指针类型。 避免重载解析歧义。传统的 0 和 NULL 在函数重载中会引起歧义。...使用override声明重写函数 C++中子类可以重写基类的虚函数,但两者必须完全相同,才会被编译器认定为是重写的函数; 否则会被认定为子类自身的函数成员,且编译器不会提醒。...a在编译时不会提示错误,b在加上override后,明确声明此为重写接口,编译器在查询基类,编译报错无此接口。...因此,在使用noexcept修饰函数时,需要仔细考虑函数的实现,确保不会出现意外的异常抛出。 15. 尽可能的使用constexpr constexpr是用于声明常量表达式的关键字。...让const成员函数线程安全 const成员函数意味着只读,因此这种函数在使用时会被默认为线程安全。但在实际编码中,实现的const成员函数可能存在线程不安全的情况。

    20320

    C++:22 再议const的作用(上)

    我在C++:18篇里说过const的用法,这里我有必要再提升进阶下const的理解。 因为你可能只知道他是怎么用的,但是他为什么这样用,其他用法呢? 首先回顾下const有什么主要的作用?...然而,其值在编译时不能被使用,因为编译器在编译时不需要知道存储的内容。自然,作为数组的大小就不行了。 在函数中声明的形参,在函数被调用时会得到实参的值。但是如果在类中呢?...“=”的左边,但在类中仍可以用一个指针来修改其值。)...这要看具体情况:如果在非const成员函数中,this指针只是一个类类型的;如果在const成员函数中,this指针是一个const类类型的;如果在volatile成员函数中,this指针就是一个volatile...A、作为非静态的类成员时; B、用于集合时; C、被取地址时; D、在main函数体内部通过函数来获得值时; E、const的 class或struct有用户定义的构造函数、析构函数或基类时;。

    86920

    TypeScript: 请停止使用 any

    我们看到的大多数用法都表明我们正在处理 TypeScript 中的基本类型。在文档中我们可能会找到: (…)来不使用 TypeScript 或第3方库编写的代码的值。...有些参数很难正确输入,但是 any 更容易 如果我们没有正确地输入,我们将会编写错误,比我们在动态语言中会编写更多的错误,因为我们强制 TypeScript ,一种静态类型语言,去检查不正确的类型。...但在确定特定类型之前,我们将不允许使用这些值。...我已经通过必要的运行时检查以防御性的方式编写了代码,以确保没有错误 现在可能没有错误,但是除非你有很好的测试覆盖率,否则以后来修改代码的人不会相信他们不是在错误中重构;就好像编译器不会帮你,因为我们说过它不会帮你...但是只有在尝试其他所有方法之后才推荐使用。如果使用它,我们应该将其重新转换为可预测的类型。 如果我们的函数可以真正处理任何类型,那么这种情况很少见,并且是偶然的(例如调试或日志记录函数)。

    1.2K21

    【C++】类和对象(中)--上篇

    一、类的六个默认成员函数 如果有个类中什么成员都没有,那么被称为空类 由编译器自动生成的成员函数称为默认成员函数 空类中会自动生成六个默认成员函数,这六个默认成员函数在每个类中都会自动生成 ①初始化功能的构造函数...,未显式定义则自动生成 (4)生命周期结束时自动调用 构造函数+析构函数改造栈: class Stack { public://公共访问,但在类中可以访问private的内容,只是在类外不能直接访问...(3)若未显式定义,编译器会生成默认的拷贝构造函数,这个默认的拷贝构造函数是值拷贝 在编译器生成的默认拷贝函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的 class...,是调用的编译器自动生成的拷贝构造函数 在执行析构函数的时候出现了错误,这里的原因是数组a已经被释放了,再次释放产生错误 因为编译器自动生成的拷贝构造函数是值拷贝,所以在生成s2时,s2中的指针...a指向的数组与s1中的指针指向的数组相同,在程序结束时,调用析构函数释放了s2,对应的这块数组空间也被释放,然后调用析构函数释放s1,已经被释放的空间不能被再次释放,所以出现了这样的错误,所以我们需要自己显式定义一个拷贝构造函数

    7310

    第 13 章 拷贝控制

    编译器略过了拷贝构造函数 在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照它们在类中出现的顺序进行初始化。...// 错误,析构函数是删除的 NoDtor *p = new NoDtor(); // 正确,但是不能 delete p delete p; // 错误 在某些情况下,编译器会将合成的拷贝控制成员定义为删除的...---- 13.2 拷贝控制和资源管理 在定义拷贝操作时,可以使类的行为看起来像一个值或者一个指针。...与拷贝操作不同,移动操作永远不会隐式地定义为删除的函数。如果既没有显式地要求生成=default的移动操作,又不满足编译器合成移动操作的条件,编译器根本就不会合成它们。...引用限定符必须同时出现在函数的声明和定义中。

    1K50

    C++:10---再议拷贝构造函数

    一、概念 使用一个已经存在的对象,去构造(初始化)另一个对象 二、格式 参数加上const&,因为拷贝构造函数在几种情况下都会被隐式地使用,因此拷贝构造函数不应该是explict的 const:防止函数内部修改值...&:防止无限循环拷贝 类名(类名 const& 参数名) { 函数体 } 三、拷贝构造函数的分类 浅拷贝:成员变量无动态内存(指针等)变量时,在拷贝构造函数内对成员变量只做简单的赋值,不做内存申请 深拷贝...九、绕过拷贝构造函数 在拷贝初始化过程中,编译器可以(但不是必须)跳过拷贝/移动构造函数,直接创建对象 但是,即使编译器库绕过了拷贝/移动构造函数,但在这个程序点上,拷贝/移动构造函数必须是存在且可访问的...此析构函数会delete ret和hp中的指针成员。但这两个对象包含相同的指针值。此代码会导致此指针被delete两次,这显然是一一个错误(参见12.1.2 节,第411页)。...十三、浅拷贝错误演示 原因:下列代码中,other->name指向一块内存,直接把other->name赋值给this->name,则两个变量都指向同一块内存,虽然不会出错,但是对不同的指针操作,会改变另一个指针的内容

    74920

    C++中的提供的四种类型转换方式;

    3、函数调用中的类型转换 参数传递:当函数参数的类型与传入的值类型不完全一致时,如果可以进行隐式转换,编译器会自动进行转换。...(比如void*与其他类型指针在符合逻辑的情况下)。...std::bad_cast& e) {} 应用场景:这种运行时类型检查机制使得在复杂的类层次结构中,可以安全地进行向下转型操作,尤其是当通过基类指针或引用操作对象,但在某些情况下需要访问派生类特有的成员或功能时非常有用...它主要用于在函数中,当一个参数被声明为const,但函数内部需要修改这个值的情况(这种情况通常表明设计可能存在问题,但在某些特定场景下有其用途)。...但这种转换几乎不进行任何类型检查,很容易导致程序出现严重的错误,如内存访问违规、数据损坏等。

    8110

    【C++】入门基础介绍(下)输入输出,函数重载,缺省与引用

    函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。...引用返回值的场景相对比较复杂,这里简单介绍一下场景,还有一些内容在后续类和对象的博客中会继续深入探讨。 使用引用返回值时要注意,引用的本质是简化了的指针,返回的值不能是局部变量,不然会导致野引用。...const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大。...//注意这里发生了隐式类型转换,编译不通过 return 0; } 这样一些场景下a * 3的和结果保存在一个临时对象中,int& e = d也是类似,在类型转换中会产生临时对象存储中间值,也就是说,...在C++11中引入nullptr,nullptr是一个特殊的关键字,nullptr是一种特殊类型的字面量,它可以转接成任意其他类型的指针类型。

    13010

    【C++】类和对象核心总结

    在C++中为了更好的封装,以及更好的将现实生活抽象化为计算机世界,采用面向对象的思想帮助程序猿能够对用户需求进行抽象思维化,不得不需要类class的出现。...,空指针马,那就是什么都没有,它里面是空的,所以无论你是对空指针进行成员访问或是解引用,其实都会报运行错误,注意是运行错误,而不是编译错误,只有在程序跑起来时,编译器才会报运行错误,语法检查上面,编译器认为你的这两个行为是合理的...编译阶段,语法检查不会报错 运行起来会发生错误。 五、类的六个默认成员函数 我们上面提到过类型占一个字节的空类,空类中什么都没有吗?还是他有但是我们看不到?...所以,只要你不作,你就不用写这两个重载,编译器默认生成的就够用 六、const修饰的类成员函数(const修饰的是成员函数中隐含的this指针所指向的内容,const T* const this) 1....将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数 隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

    76330

    第7章 类

    所以在函数体中可以随意使用类中出现的其他成员而不用在乎出现的先后次序。 一些函数在概念上属于类但是不定义在类中,则该函数的声明应与类在同一个头文件内。...如果一个类没有声明任何构造函数时,编译器会自动生成默认构造函数。然而某些类不能依赖于合成的默认构造函数。 一旦定义了其他的构造函数,除非自己定义一个默认函数,否则此类将没有构造函数。...class A{ int i; // 错误,默认初始化时 i的值是未定义的 }; class B{ int i = 0; // 正确 }; 编译器不能为某些类合成默认的构造函数...例如,如果类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数,那么编译器将无法初始化该成员。...因此,最好令构造函数初始值的顺序与成员函数的声明顺序一致,且避免用某些成员的值初始化其他成员。

    85040

    总结c++ primer中的notes

    unsigned 类型的对象可能永远不会保存负数。有些语言中将负数赋给 unsigned 类型是非法的,但在 C++ 中这是合法的。...不幸的是,含有未定义行为的程序在有些环境或编译器中可以正确执行,但并不能保证同一程序在不同编译器中甚至在当前编译器的后继版本中会继续正确运行,也不能保证程序在一组输入上可以正确运行且在另一组输入上也能够正确运行...在函数体外定义的变量都初始化成 0(全局变量和static变量都会被自动初始化为0),在函数体里定义的内置类型变量不进行自动初始化(编译器一般会分配给它一个随机值)。...引用 引用就是对象的别名。在实际程序中,引用主要用作函数的形式参数。 引用是一种复合类型(另外两种复合类型:指针和数组),通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。...(因为程序中定义只能出现一次,如果含有定义头文件包含在多个源文件之中,就会出现重复定义) 一些 const 对象定义在头文件中 如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义

    1.6K90
    领券