C++继承中关于从虚基类继承的函数都是虚函数的问题。(关键词virtual)

随笔 - 157&
评论 - 32&
&&&&&&&&&&&
类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就可以通过重写虚拟函数来实现对基类虚拟函数的覆盖。当基类Base的指针point指向派生类Derived的对象时,对point的print函数的调用实际上是调用了Derived的print函数而不是Base的print函数。这是面向对象中的多态性的体现&
基类的函数调用如果有virtual则根据多态性调用派生类的,如果没有virtual则是正常的静态函数调用,还是调用基类的。
class Base
public:Base(){}
virtual void print(){cout&&"Base";}
class Derived:public Base
public:Derived(){}
void print(){cout&&"Derived";}
int main()
Base *point=new Derived();
point-&print();
Output:Derived
2.纯虚函数:C++语言为我们提供了一种语法结构,通过它可以指明,一个虚拟函数只是提供了一个可被子类型改写的接口。但是,它本身并不能通过虚拟机制被调用。这就是纯虚拟函数(purevirtual function)。 纯虚拟函数的声明如下所示:class Query {public:// 声明纯虚拟函数virtual ostream& print( ostream&=cout ) const = 0;// ...};这里函数声明后面紧跟赋值0。
包含一个或多个纯虚拟函数的类被编译器识别为抽象基类。抽象基类不能被实例化,一般用于继承。
3.虚拟继承(virtual public)
在多继承下,虚继承就是为了解决菱形继承中,B,C都继承了A,D继承了B,C,那么D关于 A的引用只有一次,而不是 普通继承的 对于A引用了两次&&
格式:可以采用public、protected、private三种不同的继承关键字进行修饰,只要确保包含virtual就可以了。
void f1(){};
class B : public virtual
void f2(){};
虚继承:在继承定义中包含了virtual关键字的继承关系;虚基类:在虚继承体系中的通过virtual继承而来的基类,
了解下概念,至于虚基类的初始化、以及虚继承体系的进一步继承问题暂不讨论。
(C++标准中(也是很自然的)选择在每一次继承子类中都必须书写初始化语句(因为每一次继承子类可能都会用来定义对象),而在最下层继承子类中实际执行初始化过程。所以上面在每一个继承类中都要书写初始化语句,但是在创建对象时,而仅& 仅会在创建对象用的类构造函数中实际的执行初始化语句,其他的初始化语句都会被压制不调用。)
阅读(...) 评论()C++虚基类的作用、用法和意义
教科书上面对C++虚基类的描述玄而又玄,名曰“共享继承”,名曰“各派生类的对象共享基类的的一个拷贝”,其实说白了就是解决多重多级继承造成的二义性问题。例如有基类B,从B派生出C和D,然后类F又同时继承了C和D,现在类F的一个对象里面包含了两个基类B的对象,如果F访问自己的从基类B那里继承过来的的数据成员或者函数成员那么编译器就不知道你指的到底是从C那里继承过来的B对象呢还是从D那里继承过来的B对象。
于是虚基类诞生了,将C和D的继承方式改为虚继承,那么F访问自己从B那里继承过来的成员就不会有二义性问题了,也就是将F对象里的B对象统一为一个,只有一个基类B对象,下面是一段代码说明了对虚基类的使用。
#include &iostream&
void showa(){cout&&"i="&&i&&}
class B:virtual public A
//此处采用虚继承
class C:virtual public A
//此处采用虚继承
class D:public B,public C
int main()
a.showa();
b.showa();
c.showa();
d.showa();
//cout && "Hello world!" &&
从这个代码我们可以看出B,C,D从A那里继承过来了i这个变量并且它们之间不会有任何影响,如果B和C不是虚继承方式的,那么d.i=4;就不能编译通过了。
如果想和我愉快的玩耍,请关注公众号致新(zhixin991),或者扫描二维码
c++中的 虚函数 纯虚函数 虚基类
C++虚基类作用
C++全局对象初始化依赖关系处理
10道C++输出易错笔试题收集
C++ 虚基类的定义、功能、规定
【编程语言】C++继承和派生类、虚基类
C++虚基类的作用
c++源码分析继承问题
C++虚继承和虚基类;虚函数与继承
没有更多推荐了,C++多态、接口和虚基类的深入理解
表述一:在面向对象语言中,接口的多种不同实现方式即为多态。多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数。
表述二:基类指针(或引用)的多种状态,即基类指针所指对象的真实身份为基类则调基类中的函数表现基类的行为,为派生类则调派生类的函数表现为派生类的行为。作用是使基类指针或引用统一管理各类对象,是基于虚函数实现。
理解:多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的。
多态可以让父类的指针有“多种形态”,这是一种泛型技术。(所谓泛型技术,就是试图使用不变的代码来实现可变的算法)。
2.1虚函数定义
在基类的类定义中,定义虚函数的一般形式:
Virtual 函数返回值类型 虚函数名(形参表)
虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public。
2.2 虚函数的作用
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数进行重新定义(形式同上)。在派生类中定义的函数应与虚函数具有相同的形参个数和形参类型(覆盖),以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
虚函数可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时,基类虚成员函数调用基类指针,则会调用其真正指向的对象的成员函数,而不是基类中定义的成员函数(只要派生类改写了该成员函数)。若不是虚函数,则不管基类指针指向哪个派生类对象,调用时都会调用基类中定义的那个函数。
2.3 实现动态联编需要三个条件:
1)必须把需要动态联编的行为定义为类的公共属性的虚函数;
2)类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来;
3)必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
2.4 定义虚函数的限制
1)非类的成员函数不能定义为虚函数,类的成员函数中静态成员函数和构造函数也不能定义为虚函数,但可以将析构函数定义为虚函数。
2)只需要在声明函数的类体中使用关键字“virtual”将函数声明为虚函数,而定义函数时不需要使用关键字“virtual”。
3)如果声明了某个成员函数为虚函数,则在该类中不能出现和这个成员函数同名并且返回值、参数个数、参数类型都相同的非虚函数。在以该类为基类的派生类中,也不能出现这种非虚的同名同返回值同参数个数同参数类型函数。
1)为什么类的静态成员函数不能为虚函数:
如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义(在内存中只有一份拷贝,通过类名或对象引用访问静态成员)本身就是相矛盾的。
2)为什么构造函数不能为虚函数:
因为如果构造函数为虚函数的话,它将在执行期间被构造,而执行期则需要对象已经建立,构造函数所完成的工作就是为了建立合适的对象,因此在没有构建好的对象上不可能执行多态(虚函数的目的就在于实现多态性)的工作。在继承体系中,构造的顺序就是从基类到派生类,其目的就在于确保对象能够成功地构建。构造函数同时承担着虚函数表的建立,如果它本身都是虚函数的话,如何确保vtbl的构建成功呢?
3)虚析构函数
C++开发的时候,用来做基类的类的析构函数一般都是虚函数。当基类中有虚函数的时候,析构函数也要定义为虚析构函数。如果不定义虚析构函数,当删除一个指向派生类对象的指针时,会调用基类的析构函数,派生类的析构函数未被调用,造成内存泄露。
虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这样,当删除指向派生类的指针时,就会首先调用派生类的析构函数,不会有内存泄露的问题了。
一般情况下,如果类中没有虚函数,就不用去声明虚析构函数。当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
2.6虚函数的实现——虚函数表
虚函数是通过一张虚函数表来实现的,简称V-Table。类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址。编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享,类的每个虚函数成员占据虚函数表中的一行。
在这个表中,主要是一个类的虚函数的地址表。这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。在有虚函数的类的实例中,分配了指向这个表的指针的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就指明了实际所应该调用的函数。
3. 纯虚函数
许多情况下,在基类中不能对虚函数给出有意义的实现,则把它声明为纯虚函数,它的实现留给该基类的派生类去做。
纯虚函数的声明格式:virtual &函数返回类型说明符& &函数名& ( &参数表& )=0;
纯虚函数的作用是为派生类提供一个一致的接口。
4.抽象类(abstract class)
抽象类是指含有纯虚函数的类(至少有一个纯虚函数),该类不能创建对象(抽象类不能实例化),但是可以声明指针和引用,用于基础类的接口声明和运行时的多态。
抽象类中,既可以有抽象方法,也可以有具体方法或者叫非抽象方法。抽象类中,既可以全是抽象方法,也可以全是非抽象方法。一个继承于抽象类的子类,只有实现了父类所有的抽象方法才能够是非抽象类。
接口是一个概念(确切的说,C++中没有具体定义接口的形式)它在C++中用抽象类来实现,在C#和Java中用interface来实现。
接口是专门被继承的。接口存在的意义也是被继承。和C++里的抽象类里的纯虚函数是相同的。不能被实例化。
定义接口的关键字是interface,例如:   
public interface MyInterface{   
public void add(int x,int y);   
public void volume(int x,int y,int z);   
继承接口的关键字是implements,相当于继承类的extends。需要注意的是,当继承一个接口时,接口里的所有函数必须全部被覆盖。
当想继承多个类时,开发程序不允许,报错。这样就要用到接口。因为接口允许多重继承,而类不允许(C++中可以多重继承),所以就要用到接口。
以下是一个简单的例子,有助于理解C++的多态性和接口:
#include &iostream&
/*抽象类作为接口类举例*/
class Shape
virtual double area() = 0;//纯虚函数,纯虚函数首先与子类的对应函数属重载函数,除了形参可不相同(相同为重写),返回值类型等都相同。
protected:
};//抽象类,不能直接声明对象,仅作接口类使用。
class Trigon :public Shape
double area(){return a*b/2;}
Trigon(double x, double y){a = b =}
protected:
class Square :public Trigon
double area(){return a*b;}
Square():Trigon(0,0){cout&&"执行了"&&};//自定义一个构造函数;可配合下一个注释代码测试,验证下一个注释的内容。
Square(double j, double k):Trigon(j,k){}//通过Trigon()为继承而来的保护成员a\b赋值,使得条理更清晰。
protected:
class Circle :public Square
Circle(double r){radius =}//未显性指明调用父类的构造函数时,默认调用父类的没有形参的默认构造函数。而父类Square已有自定义的构造函数,系统就不再为其提供任何构造函数了,故报错。
Circle(double r):Square(0,0){radius =}//显性指明调用父类的构造函数。
double area(){return radius*radius*3.14;}
protected:
void main()
bool quit =
cout&&"请选择:(0)退出(1)三角形的面积(2)矩形的面积(3)圆的面积.\n";
switch (choice)
p = new Trigon(2.58,3.69);//三角形
cout&&p-&area()&&
p = new Square(23.6,5.666);//矩形
cout&&p-&area()&&
p = new Circle(6.866);
cout&&p-&area()&&
cout&&"请输入0到3的数字:"&&
if (choice&0 && choice&=3)
//当输入有效时释放堆中内存空间
在派生类继承基类时,加上一个virtual关键词则为虚拟基类继承,如:
class derive : virtual public base
虚基类是相对于它的派生类而言的,它本身可以是一个普通的类。只有它的派生类虚继承它的时候,它才称作虚基类,如果没有虚继承的话,就称为基类。比如类B虚继承于类A,那类A就称作类B的虚基类,如果没有虚继承,那类B就只是类A的基类。虚继承主要用于一个类继承多个类的情况,避免重复继承同一个类两次或多次(菱形继承问题)。
例如 由类A派生类B和类C,类D又同时继承类B和类C,这时候类D就要用虚继承的方式避免重复继承类A两次。
7. 抽象类VS接口
(注意以下的说法不针对C++)
一个类可以有多个接口,只能继承一个父类;
抽象类可以有构造方法,接口中不能有构造方法;
抽象类中可以有普通成员变量,接口中没有普通成员变量;
接口里边全部方法都必须是abstract的,抽象类的可以有实现了的方法;
抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型;
抽象类中可以包含静态方法,接口中不能包含静态方法;
抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
8. 虚函数VS纯虚函数
引入原因:为了方便使用多态特性,我们常常需要在基类中定义虚函数。纯虚函数
引入原因:
1)同“虚函数”;
2)在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
纯虚函数就是基类只定义了函数体,没有实现过程。纯虚函数相当于接口,不能直接实例hu,需要派生类来实现函数定义;
有的人可能在想,定义这些有什么用?
比如你想描述一些事物的属性给别人,而自己不想去实现,就可以定义为纯虚函数。说的再透彻一些,比如盖楼房,你是老板,你给建筑公司描述清楚你的楼房的特性,多少层,楼顶要有个花园什么的,建筑公司就可以按照你的方法去实现了,如果你不说清楚这些,可能建筑公司不太了解你需要楼房的特性。用纯需函数就可以很好的分工合作了。
二者的区别:
1& 类里声明为虚函数的话,这个函数是实现的,哪怕是空实现,它的作用就是为了能让这个函数在它的子类里面可以被重载,这样的话,编译器就可以使用后期绑定来达到多态了;
纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现。
2&虚函数在子类里面也可以不重载的;但纯虚必须在子类去实现,这就像Java的接口一样。通常我们把很多函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为你很难预料到父类里面的这个函数在子类里面如何去修改它的实现;
3&虚函数的类用于“实作继承”,继承接口的同时也继承了父类的实现。当然我们也可以完成自己的实现。纯虚函数的类用于“介面继承”,主要用于通信协议方面。关注的是接口的统一性,实现由子类完成。一般来说,介面类中只有纯虚函数的;
4&带纯虚函数的类叫抽象类,这种基类不能直接生成对象,而只有被继承,并重写其虚函数后,才能使用。
选择困难症!接口?虚基类?
虚函数表指针、虚基类表指针
关于虚基类指针向派生类指针转化
C++ 虚继承实现原理(虚基类表指针与虚基类表)
浅谈C++虚继承及虚基类表
虚继承与虚基类的本质(介绍的非常详细)
C++多态深入理解
深入理解C++三大特性之一 ——多态
多态实现原理-虚函数表内存分析及虚基类表的内存分析
没有更多推荐了,类(空类/虚基类等)占内存的空间
一、真空类
class CNull
内存结构:
评注:长度其实为0,这个字节作为内容没有意义,可能每次都不一样。
class CNull2
CNull2(){printf("Construct/n");}
~CNull2(){printf("Desctruct/n");}
void Foo(){printf("Foo/n");}
内存结构:
评注:同真空类差不多,内部的成员函数并不会影响类大小。
三、简单类
class COneMember
COneMember(int iValue = 0){m_iOne = iV};
内存结构:
00 00 00 00 //m_iOne
评注:成员数据才影响类大小。
四、简单继承
class CTwoMember:public COneMember
内存结构:
00 00 00 00 //m_iOne
CC CC CC CC //m_iTwo
评注:子类成员接在父类成员之后。
五、再继承
class CThreemember:public CTwoMember
CThreemember(int iValue=10) {m_iThree = iV};
内存结构:
00 00 00 00 //m_iOne
CC CC CC CC //m_iTwo
0A 00 00 00 //m_iThree
评注:孙类成员接在子类之后,再再继承就依此类推了。
六、多重继承
class ClassA
ClassA(int iValue=1){m_iA = iV};
class ClassB
ClassB(int iValue=2){m_iB = iV};
class ClassC
ClassC(int iValue=3){m_iC = iV};
class CComplex :public ClassA, public ClassB, public ClassC
CComplex(int iValue=4){m_iComplex = iV};
内存结构:
01 00 00 00
02 00 00 00
03 00 00 00
04 00 00 00
评注:也是父类成员先出现在前边,我想这都足够好理解。
七、复杂一些的继承
不写代码了,怕读者看了眼花,改画图。
内存结构:
01 00 00 00 //A
02 00 00 00 //B
03 00 00 00 //C
04 00 00 00 //Complex
00 00 00 00 //OneMember
CC CC CC CC //TwoMember
0A 00 00 00 //ThreeMember
05 00 00 00 //VeryComplex
评注:还是把自己的成员放在最后。
只要没涉及到“虚”(Virtual),我想没什么难点,不巧的是“虚”正是我们要研究的内容。
八、趁热打铁,看“虚继承”
class CTwoMember:virtual public COneMember
内存结构:
E8 2F 42 00 //指针,指向一个关于偏移量的数组,且称之虚基类偏移量表指针
CC CC CC CC // m_iTwo
00 00 00 00 // m_iOne(虚基类数据成员)
评注:virtual让长度增加了4,其实是多了一个指针,关于这个指针,确实有些复杂,别的文章有具体分析,这里就不岔开具体讲了,可认为它指向一个关于虚基类偏移量的数组,偏移量是关于虚基类数据成员的偏移量。
九、“闭合”虚继承,看看效果
内存结构:
14 30 42 00 //ClassB的虚基类偏移量表指针
02 00 00 00 //m_iB
C4 2F 42 00 //ClassC的虚基类偏移量表指针
03 00 00 00 //m_iC
04 00 00 00 //m_iComplex
01 00 00 00 //m_iA
评注:和预料中的一样,虚基类的成员m_iA只出现了一次,而且是在最后边。当然了,更复杂的情况要比这个难分析得多,但虚继承不是我们研究的重点,我们只需要知道:虚继承利用一个“虚基类偏移量表指针”来使得虚基类即使被重复继承也只会出现一次。
十、看一下关于static成员
class CStaticNull
CStaticNull(){printf("Construct/n");}
~CStaticNull(){printf("Desctruct/n");}
static void Foo(){printf("Foo/n");}
static int m_iV
内存结构:(同CNull2)
评注:可见static成员不会占用类的大小,static成员的存在区域为静态区,可认为它们是“全局”的,只是不提供全局的访问而已,这跟C的static其实没什么区别。
十一、带一个虚函数的空类
class CVirtualNull
CVirtualNull(){printf("Construct/n");}
~CVirtualNull(){printf("Desctruct/n");}
virtual void Foo(){printf("Foo/n");}
内存结构:
00 31 42 00 //指向虚函数表的指针(虚函数表后面简称“虚表”)
41 10 40 00 //指向虚函数Foo的指针
E9 78 02 00 00 E9 C3 03 … //函数Foo的内容(看不懂)
评注:带虚函数的类长度就增加了4,这个4其实就是个指针,指向虚函数表的指针,上面这个例子中虚表只有一个函数指针,值就是“0x”,指向的这个地址就是函数的入口了。
十二、继承带虚函数的类
class CVirtualDerived : public CVirtualNull
CVirtualDerived(){m_iVD=0xFF;};
~CVirtualDerived(){};
int m_iVD;
内存结构:
3C 50 42 00 //虚表指针
FF 00 00 00 //m_iVD
0042503C:(虚表)
23 10 40 00 //指向虚函数Foo的指针,如果这时候创建一个CVirtualNull对象,会发现它的虚表的内容跟这个一样
评注:由于父类带了虚函数,子类就算没有显式声明虚函数,虚表还是存在的,虚表存放的位置跟父类不同,但内容是同的,也就是对父类虚表的复制。
十三、子类有新的虚函数
class CVirtualDerived: public CVirtualNull
CVirtualDerived(){m_iVD=0xFF;};
~CVirtualDerived(){};
virtual void Foo2(){printf("Foo2/n");};
int m_iVD;
内存结构:
24 61 42 00 //虚表指针
FF 00 00 00 //m_iVD
23 10 40 00
50 10 40 00
评注:虚表还是只有一张,不会因为增加了新的虚函数而多出另一张来,新的虚函数的指针将添加在复制了的虚表的后面。
十四、当纯虚函数(pure function)出现时
class CPureVirtual
virtual void Foo() = 0;
class CDerivePV : public CPureVirtual
void Foo(){printf("vd: Foo/n");};
长度:4(CPureVirtual),4(CDerivePV)
内存结构:
CPureVirtual:
(不可实例化)
CDerivePV:
28 50 42 00 //虚表指针
5A 10 40 00 //指向Foo的函数指针
评注:带纯虚函数的类不可实例化,因此列不出其“内存结构”,由其派生类实现纯虚函数。我们可以看到CDerivePV虽然没有virtual声明,但由于其父类带virtual,所以还是继承了虚表,如果CDerivePV有子类,还是这个道理。
十五、虚函数类的多重继承
前面提到:(子类的虚表)不会因为增加了新的虚函数而多出另一张来,但如果有多重继承的话情况就不是这样了。下例中你将看到两张虚表。
F8 50 42 00 //虚表指针
01 00 00 00 //m_iA
02 00 00 00 //m_iB
E8 50 42 00 //虚表指针
03 00 00 00 //m_iC
04 00 00 00 //m_iComplex
5A 10 40 00 //FooA
55 10 40 00 //FooB
64 10 40 00 //FooComplex
5F 10 40 00 //FooC
评注:子类的虚函数接在第一个基类的虚函数表的后面,所以B接在A后面,Complex接在B后面。基类依次出现,子类成员接在最后面,所以m_iComplex位于最后面。
这篇文章太好了,所以必须转过来~~~~留着看~
转载地址:
没有更多推荐了,&>&C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类)
C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类)
上传大小:64KB
C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类).doc
综合评分:0
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类)
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*投诉人姓名:
*投诉人联系方式:
*版权证明:
*详细原因:
C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类)

我要回帖

更多关于 中国关键词800字范文 的文章

 

随机推荐