- 浏览: 208471 次
- 性别:
- 来自: 重庆
-
文章分类
最新评论
我评价自己的C++水平还未入门的确不够准确,应该是远远未入门。
感叹自己看书的时候如此粗心,C++Coder最基本的placement new的知识,今天才明白。
如何在new一个对象的时候,使对象的空间并不在堆上分配,而是由使用者传入一个缓冲区给对象使用,且编译期会自动调用对象的构造函数?
new这个C++头文件中(注意,是new,不是new.h),定义了一个全局的重载了的new操作符,可以达到上述的效果。看看我写的测试代码:
//------------------------------------------------------------------------
//test_new.cpp
// g++ -o test_new test_new.cpp -Wall -Werror
#include <stdio.h>
#include <new>
class MyClass
{
public:
MyClass()
{
printf("constructor, %s %d\n", __FILE__, __LINE__);
}
~MyClass()
{
printf("destructor, %s %d\n", __FILE__, __LINE__);
}
private:
MyClass(const MyClass& rsh);
MyClass& operator=(const MyClass& rsh);
};
void test()
{
char buf[10];
MyClass* p = new (buf)MyClass; // 构造函数被调用了
printf("buf=%08X, p=%08X\n", (unsigned int)buf, (unsigned int)p); //发现对象的地址和缓冲区的地址是一致的
//delete p; //不能调用delete,因为没有placement delete
}
int main()
{
test();
return 1;
}
//----------------------------------------------------------
当然,指定缓冲区的方式构造了对象,是不需要管理空间释放的工作的。
可是,如何只调用析构函数,而又不删除空间呢?
可以手动调用析构函数来实现:
p->~MyClass();
虽然有三种new的用法其一是new operator,也叫new表达式;其二是operator new,也叫new操作符。这两个英文名称起的也太绝了,很容易搞混,那就记中文名称吧。new表达式比较常见,也最常用,例如:
string* ps = new string("abc");
上面这个new表达式完成了两件事情:申请内存和初始化对象。
new操作符类似于C语 言中的malloc,只是负责申请内存,例如:
void* buffer = operator new(sizeof(string));
注 意这里多了一个operator。这是new的第二个用法,也算比较常见吧。
那么第三个用法就不很常见了,官方的说法是placement new,它用于在给定的内存中初始化对象,也就是说你手中已有一块闲置的内存,例如:
void* buffer = operator new(sizeof(string));//那么现在buffer是你所拥有闲置内存的指针
buffer = new(buffer) string("abc"); //调用了placement new,在buffer所指向的内存中初始化string类型的对象,初始值是"abc"
事实上,placement new也是new表达式的一种,但是比普通的new表达式多了一个参数,当然完成的操作和返回值也不同。
因此上面new的第一种用法可以分解两个 动作,分别为后面的两种用法。
与new对应的delete没有三种语法,它只有两种,分别是delete operator和operator delete,也称为delete表达式和delete操作符。delete表达式和new表达式对应,完成对象的析构和内存的释放操作。而delete 操作符只是用于内存的释放,和C语言中的free相似。例如:
string* ps = new string("abc"); ... delete ps; //调用delete表达式,先析构再释放 void* buffer = operator new(sizeof(string)); ... operator delete(buffer); //释放 |
那么为什么没有和 placement new对应的那个delete呢?其实是有的。placement new是在指定位置初始化对象,也就是调用了构造函数,因此与之对应的就是析构函数了,只不过它不叫placement delete而已。
void *pv = operator new(sizeof(vector<int>)); pv = new(pv) vector<int>(8, 0); ... static_cast<vector<int>* >(pv)->~vector(); // call destruct function operator delete(pv); // free memory pv = NULL; |
发表评论
-
C++的原子操作
2012-12-20 17:43 4696在多进程(线程)访问资源时,能够确保所有其他的进程(线程 ... -
匿名namespace的作用以及它与static的区别
2012-12-20 17:24 1865一。匿名namespace的作用 在C语言中,如果我们 ... -
C++类型萃取技术
2012-12-19 15:16 1157Traits技术可以用来获得一个 类型 的相关信息的。 ... -
数值压缩存储方法Varint
2012-12-19 14:35 881转自:http://www.cnblogs.com/smark ... -
TypeList
2012-12-19 13:49 1162转自:http://blog.csdn.n ... -
template <unsigned int N>
2012-12-19 11:51 1508详见:http://stackoverflow.com/ ... -
二维指针*(void **)的研究(uC/OS-II案例)
2012-12-19 22:20 3308原文 : http://blog.csdn ... -
多级指针和链表
2012-12-18 22:28 0如果看到一个声明:t ... -
理解*(void**)b
2012-12-18 22:03 0#include <stdio.h> ... -
STL标准库:Allocator能做什么
2012-12-18 20:10 0The Standard Librarian: Wha ... -
三种的allocator实现源代码的对比
2012-12-18 19:55 1353转自:http://blog.csdn.net ... -
结构体内变量相对便宜与list_entry()宏
2012-12-18 17:59 963#define list_entry(ptr, t ... -
声明与函数、函数指针---(*(void (*)( ) )0)( ) 解析
2012-12-18 17:33 1123概述 在很 ... -
c++模板(类型依赖)说明例子
2012-12-18 16:57 1171#include <iostream> # ... -
C++,永久改变你写异常安全代码的方式(神奇的Loki::ScopeGuard)
2012-12-17 20:19 2528作者:Andrei Alexandrescu and P ... -
C++的make_pair函数
2012-12-17 17:19 3536Pairs C++标准程序库中凡是“必须返回两 ... -
C++的explicit构造函数
2012-12-13 15:59 684按照默认规定,只有一个参数的构造函数也定义了一个隐式转换 ...
相关推荐
以下是`new`的三种主要用法的详细解析: 1. **Plain new**: 这是最常见的`new`使用方式,它负责分配内存并调用构造函数来初始化对象。如果分配失败,`plain new`会抛出一个`std::bad_alloc`异常。例如: ```cpp ...
new 在 C++ 中有三种使用方法:new 表达式、operator new 和 placement new。每种方法都有其特点和应用场景,程序员需要根据实际情况选择合适的方法来使用 new。同时,delete 语句也需要根据实际情况选择合适的方法...
在C++编程语言中,`new`关键字有三种主要的使用方法,这些方法可以被归类为两大类:new表达式和new操作符。每种用法都有其特定的用途和场景,对于理解和掌握C++内存管理至关重要。 首先,我们来看最常用的**new...
本文详细介绍了 C++ 中的 new,包括 new operator、operator new、placement new 三种形态的内容,并且详细解释了每一种形态的行为和用法,同时也提到了 delete 的相关知识点,希望对读者有所帮助。
有关于c++方面new和delete的用法及关注
placement new 是 C++ 中的第三种 new,用法是: ```c void *operator new (size_t, void* buffer); ``` placement new 允许你在一块已存在的内存上分配一个对象,而内存上的数据不会被覆盖或者被你主动改写。例如...
C++中的`map`是一个关联容器,它存储键值对,其中每个键都是唯一的。`map`的数据结构通常实现为红黑树,提供了O(log n)的时间复杂度进行插入、查找和...通过实例分析,我们可以更好地理解如何在C++中使用`map`容器。
### 更有效的C++编程:35种新方法提升程序与设计 #### 深入理解C++语言特性 《More Effective C++: 35 New Ways to Improve Your Programs and Designs》是一本深入探讨C++语言特性的书籍。本书不仅覆盖了C++中...
virtual用法一 #include using namespace std; class A{ public: virtual void display(){ cout<<"A"<<ENDL>display(); delete p; } int main(int argc,char* argv[]) { doDisplay(new B()); return 0; ...
C++的基本使用方法包括以下几个关键概念: 1. **语法基础**:C++的语法与C语言非常相似,包括变量声明、数据类型(如int、float、char等)、控制结构(如if语句、for循环、while循环)、函数定义和调用。 2. **类...
"C++ new 用法" C++ 中的 new 运算符是一种用于动态分配内存的操作符,主要用于分配内存空间并返回指向该空间的指针。...new 运算符是 C++ 中一种强大的动态内存分配工具,但需要小心使用,以免出现内存泄露和 Bug。
在C++中,通常需要手动处理编码转换,可能需要用到第三方库如iconv等。 总之,Java和C++通过Socket通信时,要确保双方对字符编码的一致性,避免出现乱码现象。在设计系统时,最好能统一编码标准,如都使用UTF-8,以...
C++ 中 const 用法全解 const 在 C++ 中占有重要作用,属于小兵立大功的典型,本文档详细介绍了如何使用 const。 1. const 常量 在 C++ 中,const 可以用来修饰变量,称为常量。例如:const int max = 100; 这种...
C++ API中文参考是针对C++编程语言的接口函数库的详细文档,旨在帮助开发者更好地理解和使用C++标准库以及第三方库中的API。C++ API不仅涵盖了C++标准库(如STL,即Standard Template Library)的内容,还可能包括...
内存管理主要包括动态内存分配和释放,其中new和delete是C++中进行动态内存操作的关键关键字。 首先,理解new和delete的基本用法是至关重要的。new用于在堆上分配内存,同时调用构造函数来初始化新创建的对象。例如...
**New** 与 **Delete** 是 C++ 语言中的关键字,作为运算符使用,用于动态内存的分配与释放。与 Malloc 和 Free 不同,New 和 Delete 是编译器级别的特性,而非库函数。 #### 二、动态内存分配与初始化 对于 C++ ...
2. new的三种形态:new operator、operator new、placement new。new operator是我们平时所使用的new,其行为就是前面所说的三个步骤。operator new是可以重载的,用于分配内存。placement new是用来实现定位构造的...
new可以分为三种形态:new operator、operator new、placement new。new operator是我们平时所使用的new,其行为就是前面所说的三个步骤。operator new是可以重载的,用于分配内存的操作符。placement new是用来实现...
7. **C++标准库**:讲解了标准库中的智能指针、异常处理、I/O流和locale等组件的使用,帮助读者更好地利用C++标准库提供的功能。 8. **C++11及以后的新特性**:虽然原书可能不包含这部分内容,但C++11引入了许多新...