假设我想制作一个无法构造的类型(不要问为什么).
struct Impossible
{
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
Impossible() = delete;
// disable automatically generated constructors, don't declare any others
Impossible(const Impossible&) = delete;
// I suppose this is redundant with nothing to copy
Run Code Online (Sandbox Code Playgroud)
或者像这样:
Impossible(...) = delete;
// explicitly disable all constructors
Run Code Online (Sandbox Code Playgroud)
或者像这样:
template<typename... Ts>
Impossible(Ts...) = delete;
// explicitly disable all constructors, template version
};
Run Code Online (Sandbox Code Playgroud)
我想我可以对任何函数提出同样的问题,而不仅仅是构造函数.
我选择哪一个有什么不同?在语法方面,我认为我喜欢第二种选择.但是,在任何情况下,是否有可能检测到差异(除了错误信息的文本中)?
用于删除和我们使用的元素数组delete[].是否可以按照我在下面的方式删除指针?
ClassA* object = new ClassA();
ClassA* pointer1 = object;
ClassA* object2 = new ClassA();
ClassA* pointer2 = object2;
delete pointer1,pointer2;
Run Code Online (Sandbox Code Playgroud)
为什么不能用这种方式删除?
[编辑]
我可以说,有什么缺点导致上述删除没有实现?
我已经写了下面的代码,重载new及delete运营商,并引发在析构函数的异常.
抛出异常时,为什么delete操作符中的代码没有执行(并且"再见"打印)?
如果不应该执行,(如何)释放内存?是其他delete运营商之一吗?是否会重载其中一个而导致执行相应的代码?或者内存根本没有被释放,因为破坏失败意味着它可能不应该是?
#include <iostream>
using namespace std;
class A
{
public:
A() { }
~A() noexcept(false) { throw exception(); }
void* operator new (std::size_t count)
{
cout << "hi" << endl;
return ::operator new(count);
}
void operator delete (void* ptr)
{
cout << "bye" << endl;
return ::operator delete(ptr);
}
// using these (with corresponding new's) don't seem to work either
// void operator delete (void* ptr, const std::nothrow_t& …Run Code Online (Sandbox Code Playgroud) 我想知道如何将C++ - FAQ-lite的第11.14节适用于数组.
基本上,我想要这样的东西:
class Pool {
public:
void* allocate(size_t size) {...}
void deallocate(void* p, size_t size) {...}
};
void* operator new[](size_t size, Pool& pool) { return pool.allocate(size); }
void operator delete[](void* p, size_t size, Pool& pool) { pool.deallocate(p, size); }
struct Foo {...};
int main() {
Pool pool;
Foo* manyFoos = new (pool) Foo [15];
/* ... */
delete [] (pool) manyFoos;
}
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚声明和调用它的正确语法operator delete[] (pool).有人可以帮忙吗?
我遇到了第一个改变传递给:: delete的左值的编译器,但没有将左值归零.这是以下情况:
Foo * p = new Foo();
Foo * q = p;
assert(p != 0);
assert(p == q);
::delete p;
assert(p != q);
assert(p != 0);
Run Code Online (Sandbox Code Playgroud)
请注意,删除操作后p不为零,并且已从其旧值更改.一位同事告诉我,他在使用一些将p改为0xFFFFFFFF的大型机C++编译器以及将p改为0的其他编译器的经验并不罕见.
在C++标准中,它是否允许编译器执行此操作?
通过StackOverflow搜索,我发现了这个问题:为什么不删除将指针设置为NULL?有一个答案提到Bjarne Stroustrup的答复,其中包括声明:
C++显然允许delete的实现将左值操作数归零,我曾希望实现会这样做,但这个想法似乎并没有受到实现者的欢迎.
我已经阅读并重新阅读了最终委员会草案C++ 0x标准的第5.3.5和12.5节,但我没有看到"明确"部分.我只是在寻找标准的错误部分吗?或者这些部分中是否存在一系列逻辑,但我只是没有正确连接在一起.
我没有Annotated C++ Reference Manual的副本了.编译器是否可以在ARM中执行此操作?
[编辑:将部分参考从3.5.3更正为5.3.5.我还添加了一个有趣的悖论作为Henk断言删除后p未定义的对立点.
如果将p初始化为null,则存在一个有趣的悖论.
Foo * p = 0;
Foo * q = p;
assert(p == 0);
assert(p == q);
::delete p;
assert(p == q);
assert(p == 0);
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,行为已有详细记录.当delete获得一个空指针时,它假设什么也不做,所以p保持不变.
考虑以下代码:
typedef SomeType type_t[2];
SomeType * arr1 = new type_t; //new or new[] ???
type_t * arr2 = new type_t[3]; //new or new[] ???
Run Code Online (Sandbox Code Playgroud)
根据标准,new在第一和第二案例(new或new[])中将调用哪个版本以及如何删除arr1和arr2(使用delete或delete[])?
在对项目进行了大量更改后,我创建了一个错误,我花了很长时间才追查.
我有一个包含动态分配数组的类.然后我创建了这个类的动态数组.然后我可以删除[]那个数组.但是,如果我在删除它之前替换数组中的项目,则会导致错误.在调试模式下,它提供了一个断言消息从dbgdel.cpp"表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)".这是一个小程序来演示.
class SomeClass {
public:
int *data;
SomeClass() {
data = nullptr;
}
SomeClass(int num) {
data = new int[num];
}
~SomeClass() {
if (data != nullptr) {
delete[] data;
}
}
};
int main(int argc, char *args[]) {
SomeClass *someArray = new SomeClass[10];
//If you comment this out, there is no error. Error gets thrown when deleting
someArray[0] = SomeClass(10);
delete[] someArray;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我很好奇,为什么会这样?当替换数组中的项时,将调用其析构函数.然后,新项目将数据分配在与数组不同的位置.然后delete []调用数组中所有对象的析构函数.当析构函数被调用时,它们应该删除项目的数据数组.我无法想象问题是什么,但我想如果有人能解释的话.
我不确定我是否在C++中正确理解了"大小的释放".在C++ 14中,以下签名被添加到全局范围:
void operator delete(void* ptr, std::size_t size) noexcept
Run Code Online (Sandbox Code Playgroud)
我正在使用GCC 7.1.0编译以下源代码:
#include <cstdio> // printf()
#include <cstdlib> // exit(),malloc(),free()
#include <new> // new(),delete()
void* operator new(std::size_t size)
{
std::printf("-> operator ::new(std::size_t %zu)\n", size);
return malloc(size);
}
void operator delete(void* ptr) noexcept
{
std::printf("-> operator ::delete(void* %p)\n", ptr);
free(ptr);
}
void operator delete(void* ptr, std::size_t size) noexcept
{
std::printf("-> operator ::delete(void* %p, size_t %zu)\n", ptr, size);
free(ptr);
}
struct B
{
double d1;
void* operator new(std::size_t size)
{
std::printf("-> …Run Code Online (Sandbox Code Playgroud) 我目前正在查看::delete用于删除指针的C++代码.
一个毫无意义的例子是:
void DoWork(ExampleClass* ptr)
{
::delete ptr;
}
Run Code Online (Sandbox Code Playgroud)
以这种方式使用delete关键字的目的是什么?
我正在尝试如下所示的代码:
class Example {
public:
Example(int val = 0) : m_val(val) { }
~Example() { }
void* operator new (std::size_t sz) {
std::cout << "Example created on the heap with size " << sz << std::endl;
return std::malloc(sz);
}
void* operator new[] (std::size_t sz) {
std::cout << "Example created on the heap with size " << sz << std::endl;
return std::malloc(sz);
}
void operator delete (void* ptr) noexcept {
std::cout << "Deleted from the heap" << std::endl;
std::free(ptr);
}
void …Run Code Online (Sandbox Code Playgroud) c++ ×10
delete-operator ×10
c++11 ×3
arrays ×2
new-operator ×2
pointers ×2
c++14 ×1
destructor ×1
dynamic ×1
exception ×1
lvalue ×1
memory ×1
memory-pool ×1