构造函数

c++学习笔记:多态

僤鯓⒐⒋嵵緔 提交于 2020-03-30 17:21:18
1.多态:通常是指对于同一个消息、同一种调用,在不同的场合,不同的情况下,执行不同的行为--->重载便是简单的多态 ------->指同一个操作作用于不同的对象就会产生不同的响应; 多态性分为静态多态性和动态多态性   其中函数重载和运算符重载属于静态多态性, 虚函数属于动态多态性---->C++是依靠虚函数来实现动态多态的。 2.C++编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数,称为联编:   1)在编译过程中进行的联编叫静态联编(static binding)或早期联编(early binding)。   2)在程序运行时完成,动态联编”(dynamic binding)也叫晚期联编(late binding)---->C++通过虚函数来实现动态联编 3.虚函数:vitual   1.与基类的虚函数有相同的参数个数;   2.与基类的虚函数有相同的参数类型;   3.与基类的虚函数有相同的返回类型。   注意点:1. 基类的成员函数定义为虚函数,那么,它在所有派生类中也保持为虚函数;即使在派生类中省略了virtual关键字,也仍然是虚函数。       2.构造函数不可为虚函数--->一旦为虚函数相当于重新,在构造子类时无法找到基类构造函数从而无法构造对象。       ( 1. 根据继承的性质,构造函数执行顺序是: A() B() 2. 根据虚函数的性质

C++构造函数使用的多种方法

百般思念 提交于 2020-03-30 16:44:34
// classes and uniform initialization #include <iostream> using namespace std; class Circle { double radius; public: Circle(double r) { radius = r; } double circum() {return 2*radius*3.14159265;} }; int main () { Circle foo (10.0); // functional form Circle bar = 20.0; // assignment init. Circle baz {30.0}; // uniform init. Circle qux = {40.0}; // POD-like cout << "foo's circumference: " << foo.circum() << '\n'; cout << "bar circumference: " << bar.circum() << '\n'; cout << "bazcircumference: " << baz.circum() << '\n'; cout << "qux circumference: " << qux.circum() << '\n'; return 0; }   

类的this指针

空扰寡人 提交于 2020-03-30 16:42:35
   类的this指针有以下特点:    (1)this只能在成员函数中使用。   全局函数、静态函数都不能使用this。   实际上,成员函数默认第一个参数为T* const this。   如: class A{public: int func(int p) {}}; 其中,func的原型在编译器看来应该是: int func(A* const this, int p); (2)由此可见,this在成员函数的开始前构造,在成员的结束后清除。   这个生命周期同任何一个函数的参数是一样的,没有任何区别。   当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去。如: A a;a.func(10); 此处,编译器将会编译成: A::func(&a, 10); 看起来和静态函数没差别,对吗?不过,区别还是有的。编译器通常会对this指针做一些优化,因此,this指针的传递效率比较高——如VC通常是通过ecx寄存器传递this参数的。    (3)几个this指针的易混问题。    1)this指针是什么时候创建的?   this在成员函数的开始执行前构造,在成员的执行结束后清除。   但是如果class或者struct里面没有方法的话,它们是没有构造函数的,只能当做C的struct使用。采用TYPE xx的方式定义的话,在栈里分配内存

C++语法之构造、析构函数

老子叫甜甜 提交于 2020-03-30 16:08:34
C++语法之构造、析构函数 众所周知,在类的一个对象被创建时,编译系统就会自动为该对象分配空间。但在分配空间后还会自动调用一个函数,这个函数我们就称为构造函数。构造函数的作用是为对象的成员变量赋初值。 构造函数:构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)。创建对象时,根据对象的类型不停,调用不同的构造函数。当没有定义构造函数时系统就会生成隐式的构造函数,无任何实际作用。 例如: include using namespace std; class rec { public: rec(){cout<<"构造一个长方形甲\n";} rec(int l,int w){ length = l; width = w;cout << "长方形乙的面积为:" << length * width << endl;} rec(int l,int w,int h){ length=l ; width=w ; height=h ; cout<<"长方体丙的体积为:" <<length width height<<endl;} private: int length; int width; int height; }; void main() {//下面分别调用不同的构造函数 rec a; rec b(3,4); rec c(3,4

C++ 关键字 explicit 的使用

ε祈祈猫儿з 提交于 2020-03-30 12:30:59
首先是定义: explicit关键字只能修饰只有一个参数的 构造函数 ,或者有多个参数,但是除第一个参数外其他的参数都有默认值的构造函数。它的作用是表明构造函数是显式方式显示的。(类构造函数默认为隐式) 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了 举个例子: class AMD{ public: AMD(int level){ //这里的构造函数默认就是隐式声明 ..... } ..... } 在这种情况下,如果运行以下语句: AMD a(3); AMD b=10; 这两种都是没有问题的,第二句 AMD b=10; 没有问题的原因是: C++中, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象. 也就是说 AMD b=10 在实际执行时操作等同于以下语句: AMD b(10); //或者 AMD c(10); AMD b = c; 虽然解释的通了,但是这种写法仍然是不友好的,毕竟 AMD b=10 这种写法看上去就像是将整数赋值给对象,显得不伦不类,而且在复杂代码中容易让人感到迷惑 -->所以现在就要使用到explicit关键字了 经过explicit修饰后: class AMD{ public: explicit AMD(int level){ /

函数重载(overload)和函数重写(override)

為{幸葍}努か 提交于 2020-03-30 08:12:26
1. 前言:   在C++中有两个非常容易混淆的概念,分别是函数重载( overload )和函数重写( overwirte )。虽然只相差一个字,但是它们两者之间的差别还是非常巨大的。   而通过深入了解这两个概念的区别,会对C++的面向对象机制有一个更深入的理解。 2 函数重载(overload function) 2.1 函数重载的概念: 2.1.1 概念: 当函数具有相同的名称,但是 参数列表不相同 的情形( 包括参数的 个数不同 或参数的 类型不同 ),这样的 同名而不同参数 的函数之间,互相被称之为重载函数。 2.1.2 基本条件: 函数名必须相同; 函数参数必须不相同,可以是参数类型或者参数个数不同; 函数返回值可以相同,也可以不相同。(备注: 但是如果函数的名称和参数完全相同,仅仅是返回值类型不同,是无法进行函数重载的。 ) 2.1.3 注意: 只能通过不同的参数样式进行重载,例如:不同的参数 类型 ,不同的参数 个数 ,或者不同的参数 顺序 ; 不能通过访问权限、返回类型、抛出的异常不同而进行重载; 重载的函数应该在相同的作用域下。 2.1.4 函数重载实例判断: 以下的集中写法,分别表示了哪些是重载的,哪些不是重载的。 (1) void func1( int arg1); (2) void func1( double arg1); (3) void func1(

C++:new与malloc的区别

只谈情不闲聊 提交于 2020-03-29 18:07:31
1.属性 new/delete是操作符,是C++关键字,需要编译器支持;malloc/free是库函数,需要头文件支持。 2.参数 使用new操作符动态分配内存时无需指定内存块大小,编译器会根据类型自行计算;malloc分配内存时需要显式地指出所需内存块大小。 3.返回类型 new操作符内存分配成功时会返回相应对象类型的指针,无需进行强制类型转换,符合类型安全性,分配失败时会抛出bac_alloc异常;malloc分配内存成功时会返回void*类型的指针,需要通过强制类型转换为所需类型,分配失败时返回NULL值。 4.非内部数据对象 new会先调用operator new函数,申请足够的内存,再调用类型的构造函数,初始化成员变量,最后返回自定义类型的指针;delete会先调用析构函数,然后调用operator delete函数释放内存;malloc/free是库函数,只能动态申请内存及释放内存,无法完成构造函数及析构函数的工作。 5.重载 C++允许重载new/delete(实际上是重载operator new 和operator delete),特别的,布局new(placement new)就不需要为对象分配内存,而是使用指定一个地址作为内存起始区域,new在这段内存上完成对象的构造函数调用并初始化该内存段,并返回此内存地址;malloc/free不允许重载。 6.内存区域

java中Super到底是什么意思

一个人想着一个人 提交于 2020-03-29 13:31:30
要说super就先要说this。 "this",作为一个特殊的关键字,它的规则如下: 1。可以表示构造函数传递。this(a,b)表示调用另外一个构造函数。这里面的this就是一个特殊语法,不是变量,没有什么类型。 2。可以在一个类的非static成员内部使用,表示当前这个对象。此时,this就是一个final的普通变量,它有静态类型,就是这个类C本身;它有动态类型,就是当前这个对象的类型。你可以对它调用成员函数,把它传递给别的函数,等等等等。只要一个C类型的final变量可以出现的地方,它就可以出现。 "super"。它和"this"类似,但是也有不同的地方。 1。表示调用父类的构造函数。也是一个特殊语法,不是变量,没有什么类型。 2。可以在一个类的非static成员内部使用。比如super.method()。 但是,注意,这个super.method()只是长得跟some_var.method()一样,一个语法糖而已。实质上,"super"根本不是一个变量。 为什么不是?因为如果是就坏了。java里面有一个金科玉律:任何public非static函数的调用都是多态的。 所以,如果super是个变量,也指向当前对象,那么,不管super的静态类型是什么super.method()必然调用的是子类的那个版本,而不会是我们期望的,静态地选择父类的那个版本。 所以,你只要把super

Hadoop技术内幕HDFS-笔记3之序列化

北城余情 提交于 2020-03-29 00:58:34
1.1. 序列化 org.apache.hadoop.io包 序列化:将一个对象编码为一个字节流 反序列化:相反过程 用途: 1、 作为一种持久化格式:可存储在硬盘上,供以后反序列化使用 2、 作为一种通信数据格式:可在JVM之间,通过网路相互传递 3、 复制的机制:深度复制 1.1.1. java内建序列化机制: 只有实现Serializabl接口(声明)即可。 对象输出流ObjectOutputStream 的writeObject(obj)方法 序列化输出的结果中包含了大量与类有关的信息。 对象输入流ObjectInputStream的readObject()方法,读取对象时必须小心跟踪存储对象的数量、顺序和类型 对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数会被调用(即会调用构造方法创建新的对象)。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成(即无新的对象进行构造)。 package com.test; import java.io.FileInputStream; import java.io

JavaScript中this的一些坑

本秂侑毒 提交于 2020-03-28 21:35:55
我们经常在回调函数里面会遇到一些坑: var obj = { name: 'qiutc', foo: function() { console.log(this); }, foo2: function() { console.log(this); setTimeout(this.foo, 1000); } } obj.foo2(); 执行这段代码我们会发现两次打印出来的 this 是不一样的: 第一次是 foo2 中直接打印 this ,这里指向 obj 这个对象,我们毋庸置疑; 但是在 setTimeout 中执行的 this.foo ,却指向了全局对象,这里不是把它当作函数的方法使用吗?这一点经常让很多初学者疑惑; 其实, setTimeout 也只是一个函数而已,函数必然有可能需要参数,我们把 this.foo 当作一个参数传给 setTimeout 这个函数,就像它需要一个 fun 参数,在传入参数的时候,其实做了个这样的操作 fun = this.foo ,看到没有,这里我们直接把 fun 指向 this.foo 的引用;执行的时候其实是执行了 fun() 所以已经和 obj 无关了,它是被当作普通函数直接调用的,因此 this 指向全局对象。 这个问题是很多异步回调函数中普遍会碰到的; 解决 为了解决这个问题,我们可以利用 闭包 的特性来处理: var obj = {