error C2663 重载没有“this”指针的合法转换

本文深入探讨了C++中const关键字的正确使用方法,并解析了errorC2663错误的根源及解决方案,强调了在函数声明与成员变量中正确应用const的重要性。

error C2663: “XXX”: 1 个重载没有“this”指针的合法转换
error C2663: “XXX”: 2 个重载没有“this”指针的合法转换
error C2663: “XXX”: 3 个重载没有“this”指针的合法转换
error C2663: “XXX”: n 个重载没有“this”指针的合法转换
…n++

出现上面的错误,很有可能是const使用的不正确。
(1)函数声明带有const
(2)成员变量是const
解决方法:
重载没有const的函数
或者重载有const的函数

namespace DeepMapAcad { // 前向声明一个模板类 observer_ptr,用于处理对对象的指针 template<typename T> class observer_ptr; // 用于处理引用计数对象的智能指针。 template<class T> class rhref_ptr { public: typedef T element_type; rhref_ptr() : _ptr(0) { } rhref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); } /// <summary> /// 用于创建一个新的 rhref_ptr 对象,该对象是另一个 rhref_ptr 对象的副本 /// </summary> /// <param name="rp">指向要拷贝的 rhref_ptr 对象。通过使用常量引用,可以避免不必要的拷贝,同时确保不会修改原始对象</param> rhref_ptr(const rhref_ptr& rp) : _ptr(rp._ptr) { // 检查 _ptr 是否为非空指针 if (_ptr) // 增加所指向对象的引用计数 // 这是引用计数智能指针的核心机制, // 确保在多个 rhref_ptr 对象指向同一个对象时, // 对象的引用计数会相应增加,从而避免对象被过早销毁 _ptr->ref(); } /// <summary> /// 模板拷贝构造函数 /// </summary> /// <typeparam name="Other">允许传入不同模板参数类型的 rhref_ptr 对象</typeparam> /// <param name="rp"></param> template<class Other> rhref_ptr(const rhref_ptr<Other>& rp) : _ptr(rp._ptr) // 即让两个 rhref_ptr 对象指向同一个底层指针 { if (_ptr) _ptr->ref(); } /// <summary> /// 从 observer_ptr<T> 对象创建一个 rhref_ptr 对象 /// </summary> /// <param name="optr">通常是一个弱引用指针,不拥有对象的所有权,只观察对象的生命周期</param> rhref_ptr(observer_ptr<T>& optr) : _ptr(0) { // 调用 observer_ptr 对象的 lock 方法,并将当前 rhref_ptr 对象的引用作为参数传递给它 // lock 方法的作用通常是尝试将弱引用转换为强引用。 // 如果 observer_ptr 所观察的对象仍然存在,lock 方法会使 rhref_ptr 指向该对象, // 并可能增加对象的引用计数; // 如果对象已经被销毁,lock 方法可能会保持 rhref_ptr 为 nullptr optr.lock(*this); } /// <summary> /// 管理所指向对象的引用计数,并在必要时释放对象的内存 /// </summary> ~rhref_ptr() { if (_ptr) _ptr->unref(); _ptr = 0; } /// <summary> /// /// </summary> /// <param name="rp"></param> /// <returns></returns> rhref_ptr& operator = (const rhref_ptr& rp) { // 通常是将 rp 对象的状态复制到当前对象,可能涉及到引用计数的更新、指针的复制等操作 assign(rp); // 返回当前对象的引用。这是为了支持连续赋值操作,例如 a = b = c return *this; } template<class Other> rhref_ptr& operator = (const rhref_ptr<Other>& rp) { // 将 rp 的状态复制到当前对象,最后返回当前对象的引用,以支持连续赋值操作 assign(rp); return *this; } /// <summary> /// 重载的赋值运算符函数,其功能是将一个普通指针 T* 赋值给 rhref_ptr 对象 /// inline 关键字表明该函数可能会被编译器内联展开,以减少函数调用的开销。 /// 函数返回 rhref_ptr 对象的引用,这使得该赋值操作可以支持链式赋值,例如 a = b = c /// </summary> /// <param name="ptr"></param> /// <returns></returns> inline rhref_ptr& operator = (T* ptr) { if (_ptr == ptr) return *this; T* tmp_ptr = _ptr; _ptr = ptr; if (_ptr) _ptr->ref(); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the original _ptr. // 可能需要进行一些资源释放操作,如减少引用计数等 // 这里简单假设直接释放 if (tmp_ptr) tmp_ptr->unref(); return *this; } /// <summary> /// implicit output conversion /// 类型转换运算符重载函数 它允许将 rhref_ptr 类型的对象隐式转换为 T* 类型的指针。 /// 当代码中需要一个 T* 类型的指针, /// 而实际提供的是 rhref_ptr 对象时,编译器会自动调用这个类型转换运算符, /// 将 rhref_ptr 对象转换为 T* 指针 /// </summary> #ifdef OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION // implicit output conversion operator T* () const { return _ptr; } #else /// <summary> /// comparison operators for rhref_ptr. /// 比较两个 rhref_ptr 对象是否相等 /// </summary> /// <param name="rp"></param> /// <returns></returns> bool operator == (const rhref_ptr& rp) const { // 通过比较两个 rhref_ptr 对象内部的指针 _ptr 是否相等来判定对象是否相等 return (_ptr == rp._ptr); } /// <summary> /// 用于比较当前类对象内部的指针 _ptr 和传入的指针 ptr 是否指向同一块内存地址。 /// 如果两个指针指向同一块内存地址,函数返回 true;反之,返回 false /// </summary> /// <param name="ptr"></param> /// <returns></returns> bool operator == (const T* ptr) const { return (_ptr == ptr); } /// <summary> /// 重载的 == 运算符函数,并且被声明为 rhref_ptr 类的友元函数。 /// 该函数用于比较一个类型为 T* 的指针 ptr 和 rhref_ptr 类对象 rp 内部的私有指针 _ptr 是否指向同一块内存地址。 /// </summary> /// <param name="ptr"></param> /// <param name="rp"></param> /// <returns>如果两个指针指向同一块内存地址,函数返回 true;反之,返回 false</returns> friend bool operator == (const T* ptr, const rhref_ptr& rp) { return (ptr == rp._ptr); } /// <summary> /// 重载的 != 运算符函数,用于比较两个 rhref_ptr 对象是否不相等。通常,这个函数会基于 rhref_ptr 对象内部的指针成员进行比较。 /// 该函数在需要判断两个 rhref_ptr 对象是否代表不同的资源时非常有用。 /// 例如,在容器中查找特定的 rhref_ptr 对象,或者在进行条件判断时, /// 需要确定两个 rhref_ptr 对象是否指向不同的实体 /// </summary> /// <param name="rp"></param> /// <returns>如果两个 rhref_ptr 对象内部的指针指向不同的内存地址,函数返回 true;反之,如果指向相同的内存地址,则返回 false</returns> bool operator != (const rhref_ptr& rp) const { return (_ptr != rp._ptr); } /// <summary> /// 用于比较该类对象内部的指针 _ptr 与传入的指针 ptr 是否不相等 /// 函数接受一个 const T* 类型的参数 ptr,表示一个指向 T 类型对象的常量指针。 /// const 修饰符表示该函数不会修改调用该函数的对象的状态。 /// 函数体中,通过比较 _ptr 和 ptr 的值来判断它们是否指向不同的内存地址。 /// 在使用标准库容器(如 std::vector、std::list 等)时,如果容器中存储的是自定义类对象, /// 并且需要根据对象内部的指针进行比较和查找操作, /// 重载的 != 运算符可以方便地实现这些功能 /// </summary> /// <param name="ptr"></param> /// <returns>如果 _ptr 和 ptr 指向不同的地址,函数返回 true;否则返回 false</returns> bool operator != (const T* ptr) const { return (_ptr != ptr); } /// <summary> /// 重载的 != 运算符函数,并且它被声明为 rhref_ptr 类的友元函数。 /// 这意味着该函数可以访问 rhref_ptr 类的私有成员 _ptr /// </summary> /// <param name="ptr"></param> /// <param name="rp"></param> /// <returns>比较传入的指针 ptr 和 rhref_ptr 对象 rp 内部的私有指针成员 _ptr 是否不相等。 /// 如果 ptr 和 rp._ptr 指向不同的内存地址,函数返回 true;否则返回 false</returns> friend bool operator != (const T* ptr, const rhref_ptr& rp) { return (ptr != rp._ptr); } /// <summary> /// 重载的小于运算符 < 函数。该函数是 rhref_ptr 类的成员函数, /// 因为它使用了 const 修饰,意味着调用该函数不会修改调用对象的状态 /// </summary> /// <param name="rp">接受一个 const rhref_ptr& 类型的引用 rp 作为参数,用于和当前对象进行比较。</param> /// <returns>函数的核心逻辑是比较当前对象的私有指针成员 _ptr 和传入对象 rp 的私有指针成员 _ptr 的地址大小。如果当前对象的 _ptr 指针地址小于 rp._ptr 的地址,则返回 true;否则返回 false</returns> bool operator < (const rhref_ptr& rp) const { return (_ptr < rp._ptr); } // 安全布尔值 // follows is an implementation of the "safe bool idiom", details can be found at: // “Safe bool idiom” 是一种用于安全地将类对象转换为布尔值的技术 // 在 C++ 中,直接重载 operator bool() 可能会导致意外的隐式转换, // 例如在算术运算中可能会将对象当作整数使用,从而引发难以调试的错误。 // Safe bool idiom 通过将布尔转换操作封装在一个更安全的机制中,避免了这种意外的隐式转换。 // 其核心思想是利用指向成员函数的指针, // 因为指向成员函数的指针只能在布尔上下文中使用,而不能用于其他算术或比较运算, // 从而确保了转换的安全性 // http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool // http://lists.boost.org/Archives/boost/2003/09/52856.php private: // 定义了一个类型别名 unspecified_bool_type, // 它是一个指向 rhref_ptr 类成员的指针类型, // 该成员的类型是 T*。在安全布尔惯用法的上下文中, // unspecified_bool_type 通常用于实现类的布尔转换运算符, // 以避免隐式转换带来的意外行为 typedef T* rhref_ptr::* unspecified_bool_type; public: // safe bool conversion /// <summary> /// 型转换运算符函数。此函数的作用是将 rhref_ptr 对象隐式转换为 unspecified_bool_type 类型 /// 类型转换运算符用于在布尔语境下判断对象是否有效 /// </summary> operator unspecified_bool_type() const { // valid()判断当前对象是否处于有效状态 return valid() ? &rhref_ptr::_ptr : 0; } #endif /// <summary> /// 重载的解引用运算符。在 C++ 中,当使用 * 运算符作用于对象时,会调用这个重载函数。 /// 其主要作用是模拟指针的解引用操作,使得对象的使用方式更像指针。 /// 例如, /// 若有一个自定义的智能指针类, 通过重载该运算符, /// 就可以像使用普通指针一样使用该智能指针类的对象来访问其所指向的对象 /// </summary> /// <returns></returns> T& operator*() const { #ifdef OSG_USE_REF_PTR_SAFE_DEREFERENCE if (!_ptr) { // pointer is invalid, so throw an exception throw std::runtime_error(std::string("could not dereference invalid osg pointer ") + std::string(typeid(T).name())); } #endif return *_ptr; } /// <summary> /// 对箭头运算符 -> 的重载,其作用是让对象的使用方式更像指针。 /// 通过重载该运算符,对象可以像普通指针一样使用 -> 来访问其所指向对象的成员。 /// 结合之前的 * 运算符重载函数,使得该对象在使用上与普通指针几乎没有区别 /// 首先会检查指针 _ptr 是否为空。如果为空,会抛出一个 std::runtime_error 异常, /// 提示“could not call invalid osg pointer ” 并附带类型信息, /// 避免对空指针进行操作导致的未定义行为。如果指针不为空,则直接返回该指针 /// </summary> /// <returns></returns> T* operator->() const { #ifdef OSG_USE_REF_PTR_SAFE_DEREFERENCE if (!_ptr) { // pointer is invalid, so throw an exception. throw std::runtime_error(std::string("could not call invalid osg pointer ") + std::string(typeid(T).name())); } #endif return _ptr; } /// <summary> /// 作用是返回智能指针内部所管理的原始指针 _ptr。 /// 该函数是一个常量成员函数,意味着在调用时不会修改对象的状态。 /// 通过这个函数,可以直接获取到智能指针背后的原始指针,从而可以在需要使用原始指针的场景中使用。 /// 例如,在与一些只接受原始指针的第三方库进行交互时,就可以使用 get() 函数来获取原始指针 /// </summary> /// <returns></returns> T* get() const { return _ptr; } /// <summary> /// 检查智能指针内部的原始指针 _ptr 是否为空指针 /// </summary> /// <returns>如果 _ptr 为空指针(即 _ptr == 0 或 _ptr == nullptr),则返回 true; /// 否则返回 false</returns> bool operator!() const { return _ptr == 0; } // not required /// <summary> /// 用是检查智能指针内部的原始指针 _ptr 是否为非空指针。 /// </summary> /// <returns>如果 _ptr 不是空指针(即 _ptr != 0 或 _ptr != nullptr),则返回 true,表示智能指针指向一个有效的对象;否则返回 false,表示智能指针为空</returns> bool valid() const { return _ptr != 0; } /** release the pointer from ownership by this rhref_ptr<>, decrementing the objects refencedCount() via unref_nodelete() to prevent the Object * object from being deleted even if the reference count goes to zero. Use when using a local rhref_ptr<> to an Object that you want to return * from a function/method via a C pointer, whilst preventing the normal rhref_ptr<> destructor from cleaning up the object. When using release() * you are implicitly expecting other code to take over management of the object, otherwise a memory leak will result. */ /// <summary> /// 用于释放对内部原始指针的所有权。 /// 调用 release 函数后,智能指针不再管理这块内存, /// 它会返回内部的原始指针,并且将自身的内部指针置为 nullptr /// 转移所有权: /// 当需要将智能指针管理的资源转移给其他代码部分时,可以使用 release 函数。 /// 例如,将智能指针管理的资源传递给一个不支持智能指针的旧接口。 /// 手动管理资源:在某些特定场景下,需要手动控制资源的生命周期, /// 此时可以使用 release 函数将资源从智能指针中释放出来,然后手动进行管理 /// </summary> /// <returns></returns> T* release() { T* tmp = _ptr; if (_ptr) _ptr->unref_nodelete(); _ptr = 0; return tmp; } /// <summary> /// 交换两个 rhref_ptr 对象所管理的原始指针。 /// 也就是说,调用 swap 方法后,两个 rhref_ptr 对象会互相持有对方原本管理的资源 /// 资源交换:在某些场景下,需要交换两个智能指针所管理的资源,此时可以使用 swap 方法。 /// 算法实现:在一些算法实现中,可能需要对智能指针进行交换操作, /// 使用 swap 方法可以方便地实现这一需求 /// </summary> /// <param name="rp"></param> void swap(rhref_ptr& rp) { T* tmp = _ptr; _ptr = rp._ptr; rp._ptr = tmp; } private: /// <summary> /// 用于将一个 rhref_ptr 对象的资源赋值给另一个 rhref_ptr 对象 /// </summary> /// <typeparam name="Other"></typeparam> /// <param name="rp"></param> template<class Other> void assign(const rhref_ptr<Other>& rp) { if (_ptr == rp._ptr) return; T* tmp_ptr = _ptr; _ptr = rp._ptr; if (_ptr) _ptr->ref(); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the // original _ptr. if (tmp_ptr) tmp_ptr->unref(); } // friend 声明用于允许其他类或函数访问当前类的私有成员。 // 在 rhref_ptr 类中,friend 声明可以用于允许特定的类或函数直接访问 _ptr 指针 template<class Other> friend class rhref_ptr; T* _ptr; }; /// <summary> /// 交换两个 rhref_ptr 类型对象的内容 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rp1"></param> /// <param name="rp2"></param> template<class T> inline void swap(rhref_ptr<T>& rp1, rhref_ptr<T>& rp2) { rp1.swap(rp2); } /// <summary> /// 从 rhref_ptr 类型的对象中提取其所管理的原始指针 /// 让用户可以直接访问 rhref_ptr 内部所存储的原始指针 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rp"></param> /// <returns></returns> template<class T> inline T* get_pointer(const rhref_ptr<T>& rp) { return rp.get(); } /// <summary> /// 对 rhref_ptr 类型的智能指针进行静态类型转换 /// 用途类似于标准库中的 std::static_pointer_cast, /// 主要用于在不同类型的智能指针之间进行静态类型转换。 /// 在实际编程中,当需要将一个指向某种类型的智能指针转换为指向另一种类型的智能指针时, /// 可以使用这个函数。这种转换通常在继承关系中使用, /// 例如将指向基类的智能指针转换为指向派生类的智能指针(前提是这种转换在逻辑上是安全的),或者反之 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="Y"></typeparam> /// <param name="rp"></param> /// <returns></returns> template<class T, class Y> inline rhref_ptr<T> static_pointer_cast(const rhref_ptr<Y>& rp) { return static_cast<T*>(rp.get()); } /// <summary> /// 智能指针进行动态类型转换。 /// 模板参数 T 代表转换后的目标类型,Y 代表转换前的原始类型。 /// 函数接收一个 const rhref_ptr<Y>& 类型的参数 rp, /// 也就是一个指向 Y 类型对象的 rhref_ptr 智能指针的常量引用, /// 这保证了函数不会修改传入的 rhref_ptr 对象 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="Y"></typeparam> /// <param name="rp"></param> /// <returns></returns> template<class T, class Y> inline rhref_ptr<T> dynamic_pointer_cast(const rhref_ptr<Y>& rp) { // 函数内部使用 dynamic_cast<T*>(rp.get()) 进行动态类型转换。 // rp.get() 会调用 rhref_ptr<Y> 类的 get 成员函数, // 返回其所管理的原始指针(类型为 Y*), // 然后使用 dynamic_cast<T*> 将这个 Y* 类型的原始指针尝试转换为 T* 类型的指针。 // dynamic_cast 是 C++ 中的一个类型转换操作符, // 主要用于在继承体系中进行安全的向下转换(从基类指针或引用转换为派生类指针或引用), // 它会在运行时检查类型转换合法性。 // 如果转换成功,dynamic_cast 会返回一个指向目标类型的指针; // 如果转换失败(例如,尝试将一个基类指针转换为不相关的派生类指针),则返回一个空指针。 // 最后,将转换后的 T* 指针用于构造一个新的 rhref_ptr<T> 对象并返回 return dynamic_cast<T*>(rp.get()); } /// <summary> /// 用于对 rhref_ptr 类型的智能指针进行常量性转换 /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="Y"></typeparam> /// <param name="rp"></param> /// <returns></returns> template<class T, class Y> inline rhref_ptr<T> const_pointer_cast(const rhref_ptr<Y>& rp) { // 函数内部使用 const_cast<T*>(rp.get()) 进行常量性转换。 // rp.get() 会调用 rhref_ptr<Y> 类的 get 成员函数, // 返回其所管理的原始指针(类型为 Y*), // 然后使用 const_cast<T*> 将这个 Y* 类型的原始指针进行常量性转换, // 去除或添加指针的 const 或 volatile 限定符。 // 最后,将转换后的 T* 指针用于构造一个新的 rhref_ptr<T> 对象并返回 return const_cast<T*>(rp.get()); } }
最新发布
11-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值