繁体   English   中英

运算符重载 new 和 delete 导致编译器错误

[英]operator overloading new and delete getting compiler error

我正在尝试从编程书中执行一个关于“运算符重载”的代码示例。 但是,我有以下错误:

invalid conversion from 'char' to 'void*' [-fpermissive]
      char *p= new ('$') char[100];

这就是我重载 new 运算符的方式:

void *operator new(size_t sz,int setvalue)
{
    void *p;

    p=malloc(sz);
    if(p==NULL){
        memoryWarning();
    }
    memset(p,setvalue,sz);
    return(p);
}


int main()
{
    //rest of the code;
    char *p = new ('$') char[100];
    //rest of the code
}

构建期间的控制台输出:

21:39:21 **** Incremental Build of configuration Debug for project chapter5a ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -o "src\\chapter5a.o" "..\\src\\chapter5a.cpp" 
cc1plus.exe: warning: command line option '-std=c99' is valid for C/ObjC but not for C++
<strong>..\src\chapter5a.cpp: In function 'int main()':
..\src\chapter5a.cpp:22:20: error: invalid conversion from 'char' to 'void*' [-fpermissive]
  char *p= new('$') char;*
                    ^~~~</strong>
In file included from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ext/new_allocator.h:33:0,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/i686-w64-mingw32/bits/c++allocator.h:33,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/allocator.h:46,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/string:41,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/locale_classes.h:40,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/ios_base.h:41,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ios:42,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ostream:38,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/iostream:39,
                 from ..\src\chapter5a.cpp:9:
C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/new:146:14:<strong> note:   initializing argument 2 of 'void* operator new(std::size_t, void*)'
 inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
              ^~~~~~~~</strong>

21:39:21 Build Finished (took 703ms)

您正在重载错误的运算符。

char *p = new ('$') char[100];

调用operator new[] ,而不是operator new ,因为它是一个数组 new 表达式。

所以你想超载

void *operator new[](size_t sz,int setvalue)

不是

void *operator new(size_t sz,int setvalue)

在实践中,你可能应该重载两个(你可以叫opearator newoperator new[]

当您分别重载operator newoperator new[]时,您还需要始终重载operator deleteoperator delete[]

我不知道什么memoryWarning(); 确实如此,但请注意,没有非抛出异常规范的operator new (和operator new[] )必须抛出一个异常,当分配失败时,该异常可以被catch(std::bad_alloc) 不允许返回空指针。

最后,您尝试在此处形成的operator new重载无法按照您的预期工作。

malloc不会在您分配的内存中创建任何对象。 memset (如果这里技术上允许的话)会将字符写入该内存。 然后新表达式将在该内存中创建char数组。

新创建的对象具有它们之前放置的内存的值。 相反,数组的char元素的值将是不确定的,您将需要再次初始化它们。

在这里尝试的正确方法不是重载operator new ,而是手动初始化数组,如果没有充分理由使用它,最好不要使用 C 标准库函数memset 使用例如std::fill代替(需要#include<algorithm> ):

char *p = new char[100];
std::fill(p, p+100, '$');

或者更好,使用std::string (需要#include<string> ):

std::string str(100, '$');

可以从str.data()获得指向底层char数组的指针。


另外,不要使用NULL 由于 C++11 有nullptr使用起来总是更安全。 永远不要使用NULL ,总是使用nullptr

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM