最近在敲c++的題目時,關于繼承的總會出錯,之前運用得感徑訓很好,同樣的代碼有些能通過有些卻不能通過就很頭疼
想問問在哪里有比較好的講解
比如這代碼:(計算點到原點的距離)結果不符合,只輸出第一個輸入的值
#include<iostream>
#include<cmath>
using namespace std;
class point1d
{
protected:
float x;
public:
point1d(float a)
{
x=a;
}
float distance()
{
if(x<0)
return -x;
else
return x;
}
};
class point2d:public point1d
{
protected:
float y;
public:
point2d(float a,float b):point1d(a)
{
x=a;
y=b;
}
float distance()
{
float d=sqrt(x*x+y*y);
return d;
}
};
class point3d:public point2d
{
protected:
float z;
public:
point3d(float a,float b,float c):point2d(a,b)
{
x=a;
y=b;
z=c;
}
float distance()
{
float d=sqrt(x*x+y*y+z*z);
return d;
}
};
int main()
{
int type;
cin>>type;
point1d *p;
float a,b,c;
while(type!=0)
{
switch(type)
{
case 1:
cin>>a;
p=new point1d(a);
break;
case 2:
cin>>a>>b;
p=new point2d(a,b);
break;
case 3:
cin>>a>>b>>c;
p=new point3d(a,b,c);
break;
}
cout<<p->distance()<<endl;
cin>>type;
}
}
還有更之前的版本:
#include<iostream>
#include<cmath>
using namespace std;
class point1d
{
protected:
float x;
public:
point1d(float p=0.0);//把這行注釋掉就可以通過
float distance()
{
cin>>x;
if(x<0)
return -x;
else
return x;
}
};
class point2d:public point1d//這里會報錯
{
protected:
float y;
public:
float distance()
{
cin>>x>>y;
float d=sqrt(x*x+y*y);
return d;
}
};
class point3d:public point2d
{
protected:
float z;
public:
float distance()
{
cin>>x>>y>>z;
float d=sqrt(x*x+y*y+z*z);
return d;
}
};
int main()
{
int type;
cin>>type;
while(type!=0)
{
point1d *p;
switch(type)//若這樣運行,結果不符合
{
case 1:
p=new point1d//若沒有這行這個情況會運行錯誤
cout<<p->distance()<<endl;
break;
case 2:
p=new point2d;
cout<<p->distance()<<endl;
break;
case 3:
p=new point3d;
cout<<p->distance()<<endl;
break;
}
}
}
就很暈TAT
uj5u.com熱心網友回復:
減少繼承次數或許能好點uj5u.com熱心網友回復:
你這個是錯誤的利用了繼承uj5u.com熱心網友回復:
所以才求助嘛,沒弄懂所以就錯了
uj5u.com熱心網友回復:
你的第一個問題。在于繼承。
根據里氏規則:任何基類可以出現的地方,子類一定可以出現。
你的基類是point1,你想一下,任何point1*,是否可以替換為point2和point3???
明顯不可以。
第二的問題是,c/c++語言的問題,
指標型變數都要指向具體的地址才可以計算。
所以p 必須要new以后才可以distance()
uj5u.com熱心網友回復:
又來了又來了,我敲的一個代碼報錯#include<iostream>
#include<cstring>
using namespace std;
class time
{
protected:
int second;
int minute;
int hour;
public:
void init()
{
int h,m,s;
cin>>h>>m>>s;
getchar();
hour=h;
minute=m;
second=s;
}
void operator ++()
{
second++;
if(second==60)
{
second=0;
minute++;
}
if(minute==60)
{
minute=0;
hour++;
}
}
void operator --()
{
second--;
if(second<0)
{
second=59;
minute--;
}
if(minute<0)
{
minute=59;
hour--;
}
}
};
class time_12hours:public time
{
string type;
string interval;
public:
void print()
{
cout<<interval<<" "<<hour<<":"<<minute<<":"<<second<<endl;
}
void in(string str)
{
interval=str;
}
void operator --()
{
if(hour<0)
hour=12;
}
void operator ++()
{
if(hour==60)
hour=0;
}
};
class time_24hours:public time
{
string type;
public:
void print()
{
cout<<hour<<":"<<minute<<":"<<second<<endl;
}
void operator ++()
{
if(hour==60)
hour=0;
}
void operator --()
{
if(hour<0)
hour=23;
}
};
int main()
{
int n;
cin>>n;
class time *t;
int times;
char op;
while(n!=0)
{
t->init();
op=getchar();
cin>>times;
switch(n)
{
case 121:
t=new time_12hours;
t->in("AM");
break;
case 122:
t=new time_12hours;
t->in("PM");
break;
case 24:
t=new time_24hours;
break;
}
for(int i=0;i<times;i++)
{
switch(op)
{
case '+':
t->operator ++();
break;
case '-':
t->operator --();
break;
}
}
cin>>n;
}
}
查了一下說是宏定義沖突?換個名字也不行啊
uj5u.com熱心網友回復:
你這個是錯誤的利用了繼承
所以才求助嘛,沒弄懂所以就錯了
你的第一個問題。在于繼承。
根據里氏規則:任何基類可以出現的地方,子類一定可以出現。
你的基類是point1,你想一下,任何point1*,是否可以替換為point2和point3???
明顯不可以。
第二的問題是,c/c++語言的問題,
指標型變數都要指向具體的地址才可以計算。
所以p 必須要new以后才可以distance()
還是不懂誒,在distance()之前不是已經new了嗎,吧point1替換成point2又是什么意思啊?
uj5u.com熱心網友回復:
是原則凡是基類物件出現的場合都可以用公有派生類物件取代
嗎?
我好像懂了,是要先創建物件,之后指標p=&物件,這樣對嗎?
uj5u.com熱心網友回復:
c++prime講過這個,虛函式多載和非虛函式多載的區別,非虛不建議這樣寫,因為呼叫的函式依賴于呼叫指標的型別. 舉個例子,a, b:public a, c:public b. 有一個fun是非虛, c* p=new c;
然后你試試 p->fun(); ((b*)p)->fun(); ((a*)p)->fun(); 相信你就會知道為啥不這樣寫了. 我先說答案吧,分別輸出C,B,A的fun().
uj5u.com熱心網友回復:
class a{
public:
void fun()
{
printf("a\n");
}
};
class b :public a
{
public:
void fun()
{
printf("b\n");
}
};
class c :public b
{
public:
void fun()
{
printf("c\n");
}
};
c *p = new c;
p->fun();
((b*)p)->fun();
((a*)p)->fun();
uj5u.com熱心網友回復:
操,忘記格式化代碼了。給你演示沒有delete,正式代碼不能忘記uj5u.com熱心網友回復:
#include<iostream>
#include<cstring>
using namespace std;
class student
{
int num,age;
char name[20];
public:
student()
{
num=1000;
strcpy(name,"XXX");
age=18;
}
void init(int,char [],int);
void showme();
~student()
{
cout<<"現在注銷學生物件,姓名為:"<<name<<endl;
cout<<"學號:"<<num<<endl;
cout<<"年齡:"<<age<<endl;
}
};
void student::init(int number,char n[],int a)
{
age=a;
strcpy(name,n);
num=number;
}
void student::showme()
{
cout<<"學生:"<<name<<"\t學號:"<<num<<"\t年齡:"<<age<<endl;
}
int main()
{
student *s1,*s2;
s1=new student;
s1->showme();
s2=new student;
s2->init(1001,"張三",19);
s2->showme();
delete s1;
delete s2;
return 0;
}
像這個代碼就可以指標這樣指,不明白
uj5u.com熱心網友回復:
不知道你最后這個問題具體想問啥,問問題要表達清楚前因后果轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/132810.html
標籤:C++ 語言
上一篇:大佬們,這個怎么解
下一篇:c語言作業
