C++找茬,找出代码中存在的问题
那试试找出代码的问题,给出你理由。class X
{
public:
virtual int SomeFun() = 0{ return 1;}
void AnotherFun()const
{
v = 100UL;
printf("%d",v,v);
}
private:
unsigned long v;
};
class Y : public X
{
public:
Y() : p( new int ){}
~Y(){ delete p;}
Y& operator =(Y y)
{
*p = *y.p;
}
private:
int* p;
};
void Delete(const X* x)
{
delete x;
}
void Test()
{
Y* y1 = new Y;
Y y2 = *y1;
Delete(y1);
} 我怎么觉得到处都是问题阿,首先就是看不懂:( ,怎么SomeFun后面都没用到过,定义这个纯虚函数有什么意义阿?
v = 100UL; 这句也不理解,我怎么看着像语法错误:Q
AnotherFun() 是个const函数,好像不能访问 v阿 ?
Y& operator =(Y y)
{
*p = *y.p;
}
这个为啥没有return语句阿?如何返回 Y&的?
void Delete(const X* x)
{
delete x;
}
这个*x是const的,能被delete吗?不懂:Q
还有Delete(y1)这句,是不是会造成内存泄漏阿?
SomeFun()后面没再定义过,那Y应该也是个虚类了,好像不能生成object,是不是这样啊?
我是c++菜鸟,最怕这种抽象的程序了:Q 原帖由 四香油饼 于 26-1-2012 12:53 发表 http://freeoz.org/ibbs/images/common/back.gif
我怎么觉得到处都是问题阿,首先就是看不懂:( ,怎么SomeFun后面都没用到过,定义这个纯虚函数有什么意义阿?
v = 100UL; 这句也不理解,我怎么看着像语法错误:Q
AnotherFun() 是个const函数,好像不能访问 v ...
就是有很多问题,所以才让找的。 class X
{
public:
//an additional virtual ~X() {} needed here
virtual int SomeFun() = 0{ return 1;}//pure virtual function shouldn't contain implementation
void AnotherFun()const
{
v = 100UL; //can't change member value in const method
printf("%d",v,v); //2 v with 1 '%d'
}
private:
unsigned long v;
};
class Y : public X
{
public:
Y() : p( new int ){}//p(new int(0))
~Y(){ delete p;}
Y& operator =(Y y) // Y& operator=(const Y& y)will be much better
{
*p = *y.p; // *p = *(y.p), not sure, might not needed, but add () already good code style
//return *this;
}
private:
int* p;
};
void Delete(const X* x)
{
delete x; //can't delete const pointer
}
void Test()
{
Y* y1 = new Y;
Y y2 = *y1;
Delete(y1);
} 老乞丐,这一句在Thinking in C++里说是可以这样做的
virtual int SomeFun() = 0{ return 1;}//pure virtual function shouldn't contain implementation 这个100UL是个啥表示法阿??谁能帮俺解答一下? 原帖由 四香油饼 于 27-1-2012 13:58 发表 http://www.freeoz.org/ibbs/images/common/back.gif
这个100UL是个啥表示法阿??谁能帮俺解答一下? 100 as unsigned long, 默认情况下100被解释为int 原帖由 四香油饼 于 27-1-2012 13:58 发表 http://www.freeoz.org/ibbs/images/common/back.gif
老乞丐,这一句在Thinking in C++里说是可以这样做的
virtual int SomeFun() = 0{ return 1;}//pure virtual function shouldn't contain implementation
you are right:good
http://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation 原帖由 coredump 于 27-1-2012 15:54 发表 http://www.freeoz.org/ibbs/images/common/back.gif
100 as unsigned long, 默认情况下100被解释为int
这个是属于C++标准里的么??在教材里从来没见过呢 原帖由 四香油饼 于 27-1-2012 15:59 发表 http://www.freeoz.org/ibbs/images/common/back.gif
这个是属于C++标准里的么??在教材里从来没见过呢
是C的标准用法
http://www.cplusplus.com/doc/tutorial/constants/ class X //有虚函数的类应该写虚析构函数
{
public:
virtual int SomeFun() = 0{ return 1;} // 纯虚函数没有函数体
void AnotherFun()const
{
v = 100UL; // const 不能修改成员
printf("%d",v,v); // 应该只有1个参数v, %d是int,v是long,也有问题
}
private:
unsigned long v;
};
class Y : public X // 要override 父类的纯虚函数。 有动态内存分配的,应该写拷贝构造函数和override“=”
{
public:
Y() : p( new int ){}
~Y(){ delete p;} // 加上 p = NULL;
Y& operator =(Y y)
{
*p = *y.p; // if(NULL == p)p = new int; *p = *y.p; return *this;
}
private:
int* p;
};
void Delete(const X* x)
{
delete x; // 加上 x = NULL;
}
void Test()
{
Y* y1 = new Y;
Y y2 = *y1;
Delete(y1);
}
很好的题目哦~~~
估计还有没找出来的陷阱。 老乞丐你那个printf没有答对。。。
还有 pure virtual 可以有实现, 但这不过是小知识而已,没有什么太大实际意义。 先马克。。。回头来学习 能找出毛病来,能说明什么呢? 感觉像恶作剧 class X必须有虚析构函数,否则 Delete(y1); 会调用~X(),不会调用~Y()。
详细说明如下(书上Copy来的):
// 基类与派生类的析构函数应该为虚,即加virtual 关键字例如
#include <iostream.h>
class Base
{
public:
virtual ~Base() { cout<< "~Base" << endl ; }
};
class Derived : public Base
{
public:
virtual ~Derived() { cout<< "~Derived" << endl ; }
};
void main(void)
{
Base * pB = new Derived; // upcast
delete pB;
}
输出结果为
~Derived
~Base
如果析构函数不为虚 那么输出结果为
~Base
另,coredump是在Brisbane Nokia工作吧? 看到coredump以前写的有关QT的帖子。。。
[ 本帖最后由 william_m76 于 28-1-2012 00:17 编辑 ] 我也来凑凑热闹。。
关于virtual的那个同意楼上,貌似在深入C++对象模型里面好像讲过,不过 记不清了。
printf那里面最好用%ld
我觉得最严重的一个问题是,没有定义copy constructor。注意Y y2 = *y1;这个用法,它会调用copy constructor,而不是那个重载的赋值操作符( 在本例中根本用不到它)。 因为copy constructor没有定义,那么编译器生成的那个就会做简单拷贝,就是把y1的p指针赋给个y2的p指针,两个对象的p指向相同的地方。最终可能导致crash。 原帖由 william_m76 于 27-1-2012 23:16 发表 http://www.freeoz.org/ibbs/images/common/back.gif
class Derived : public Base
{
public:
virtual ~Derived() { cout<< "~Derived" << endl ; }
};
基类dtor为虚的话,派生类不必指定virtual关键字, 将会自动为virtual, 不过总是在virtual的方法上加上virtual是个好习惯 原帖由 dbsdsun 于 27-1-2012 23:09 发表 http://www.freeoz.org/ibbs/images/common/back.gif
能找出毛病来,能说明什么呢? 感觉像恶作剧 这个例子不规范/错误的地方,的确太多, 而且有些是不应该鼓励去抓的语法陷阱/功能, 而有些是考察的C的语法.
记得哪位大牛说的来着, C++不管用了多久, 总有些你不知道的, 并且在知道了之后会大惊失色的地方, 上面那个油饼提醒我的就是, 从来不知道, 尽管都写了大半辈子的C++了.:L 原帖由 ciasom 于 27-1-2012 23:55 发表 http://www.freeoz.org/ibbs/images/common/back.gif
printf那里面最好用%ld.
对, gcc的话, 应该最多给个warning, 不会是个error 原帖由 ciasom 于 27-1-2012 23:55 发表 http://www.freeoz.org/ibbs/images/common/back.gif
没有定义copy constructor。注意Y y2 = *y1;这个用法,它会调用copy constructor,而不是那个重载的赋值操作符( 在本例中根本用不到它)。.
这点不同意, copy constructor应该是下面这样的代码才会被调用:
X x1;
X x2(x1);
这个例子中的 Y y2 = *y1;是个明确的赋值.不过对于允许copy, 尤其是应该deep copy的情况下, 的确应该同时定义operator=和copy ctor. 从这方面说, 没有copy ctor的确算错误. 原帖由 coredump 于 27-1-2012 22:17 发表 http://freeoz.org/ibbs/images/common/back.gif
对, gcc的话, 应该最多给个warning, 不会是个error
%ld 还是个warning 原帖由 coredump 于 27-1-2012 22:25 发表 http://freeoz.org/ibbs/images/common/back.gif
这点不同意, copy constructor应该是下面这样的代码才会被调用:
这个例子中的 Y y2 = *y1;是个明确的赋值.不过对于允许copy, 尤其是应该deep copy的情况下, 的确应该同时定义operator=和copy ctor. 从这方 ...
Y y2 = *y1 是copy ctor
[ 本帖最后由 finger|regnif 于 27-1-2012 23:26 编辑 ] printf("%d",v,v); 一般 警告级别 开到最高, 以及视警告如错误 的人会知道.
VS我不是太确定, GCC肯定会有警告.
[ 本帖最后由 finger|regnif 于 27-1-2012 23:49 编辑 ] 原帖由 四香油饼 于 27-1-2012 11:58 发表 http://freeoz.org/ibbs/images/common/back.gif
老乞丐,这一句在Thinking in C++里说是可以这样做的
virtual int SomeFun() = 0{ return 1;}//pure virtual function shouldn't contain implementation
这个知道的人比较少. effectiveCpp3rd里也有讲到. 比较偏的东西了. 如果你show给面试官看的话可能会有点效果.
这个在本帖中属于可有可无的问题. 除此之外其它的错误应该是靠谱并实在的.
[ 本帖最后由 finger|regnif 于 27-1-2012 23:59 编辑 ] 原帖由 dbsdsun 于 27-1-2012 21:09 发表 http://freeoz.org/ibbs/images/common/back.gif
能找出毛病来,能说明什么呢? 感觉像恶作剧
这个virtual int SomeFun() = 0{ return 1;}的确有点恶作剧. 其它的都很实在.
真正的恶作剧是这种: i++++i++i 原帖由 finger|regnif 于 28-1-2012 01:22 发表 http://www.freeoz.org/ibbs/images/common/back.gif
Y y2 = *y1 是copy ctor
临睡觉前,特意验证了下#include
using namespace std;
class X
{
public:
X& operator=(const X& other)
{
cout << "operator= called";
return *this;
}
X() {}
X(const X& other) {
cout << "copy ctor called";
}
};
int main() {
X x1, x2;
x1 = x2; //output: operator= called
X x3(x1); //output:copy ctor called
return 0;
} 原帖由 finger|regnif 于 28-1-2012 02:03 发表 http://www.freeoz.org/ibbs/images/common/back.gif
这个virtual int SomeFun() = 0{ return 1;}的确有点恶作剧. 其它的都很实在.
真正的恶作剧是这种: i++++i++i
后一种很孔乙己, 我如果面试人, 最标准的答案不是给出正确结果, 而是拒绝回答, 然后给出拒绝的理由就行.
用人做compiler的活, 不是自虐狂就是神经病, 谁写这样的代码, 被review的时候, 肯定被骂得狗血淋头:lol 原帖由 coredump 于 28-1-2012 00:35 发表 http://freeoz.org/ibbs/images/common/back.gif
......
X x1, x2;
x1 = x2; //output: operator= called
和
X x2;
X x1 = x2;
是不同的. 前一个是赋值, 后一个是copy ctor. 这也算是copy ctor和operator=要同时存在的其中一个原因.
实际开发中见过几个用 X x1=x2;然后只定义operator=不定义copy ctor, 然后出bug的. 所以做为一个茬放在这里. 原帖由 finger|regnif 于 28-1-2012 10:15 发表 http://www.freeoz.org/ibbs/images/common/back.gif
和
是不同的. 前一个是赋值, 后一个是copy ctor. 这也算是copy ctor和operator=要同时存在的其中一个原因.
实际开发中见过几个用 X x1=x2;然后只定义operator=不定义copy ctor, 然后出bug的. 所以做为一 ... 对啦, 是我没仔细看,谢谢指出:handshake 原帖由 coredump 于 28-1-2012 00:42 发表 http://freeoz.org/ibbs/images/common/back.gif
后一种很孔乙己, 我如果面试人, 最标准的答案不是给出正确结果, 而是拒绝回答, 然后给出拒绝的理由就行.
用人做compiler的活, 不是自虐狂就是神经病, 谁写这样的代码, 被review的时候, 肯定被骂得狗血淋头:lol
刚毕业的时候还真做过 i++++i 这种题目. 我也认为 拒绝回答 是最好的答案. 其实对这种类似的语句, 很可能是未定义行为, 不同编译器实现不一样, 没有sequence point没有答案, .
页:
[1]
2