1 Востаннє редагувалося Anddep (05.04.2013 18:48:49)

Тема: Наслідування класів!

Ось роблю завдання і така проблема!
Сама суть наслідування працює, але при обчисленні значень виводить нереальний результат!.

"main.cpp"

#include<iostream>
#include "Shape3D.h"
#include "Sphere.h"
#include "Cube.h"
using namespace std;
void main(void)
{
    setlocale(0,"");
    float a,b,c; int i;
    while(1)
    {
        cout<<"\n МЕНЮ: \n1-Куб\n2-Сфера\n3-Вихiд:\n";
        cin >> i;
        switch(i)
        {
        case 1:
            {
                cout << "Куб:\n";
                cout << "Введiть довжину ребра куба:\n";
                cin >> a;
                Cube *tri;
                tri =new Cube(a);
                cout<<"Площа:" << tri->Area()<<"\n";
                cout<<"Об'єм:"<<tri->Volume()<<"\n";
                tri->PrintMessage();
                delete[] tri;
                break;
            }
        case 2:
            {
                cout<< "Сфера:\n";
                cout << "Введiть радiус сфери:\n";
                cin >> a;
                Sphere *rec;
                rec =new Sphere(a);
                cout<< "\n"<<"Площа поверхні:" << rec->Area();
                cout<< "\n"<< "Об'єм:"<<rec->Volume()<<"\n";
                rec->PrintMessage();
                delete [] rec;
                break;
            }
        case 3:
            {
                return;
            }
        }
    }

}

"Shape3D.h"

#ifndef SHAPE3D_H
#define SHAPE3D_H
#include <iostream>

using namespace std;

class Shape3D
{
public:
    Shape3D();
    virtual ~Shape3D();
    virtual float Area()=0;
    virtual float Volume()=0;
    virtual void PrintMessage();
};
#endif

"Shape3D.cpp"

#include"Shape3D.h"
#include<iostream>
using namespace std;
Shape3D::Shape3D()
{
    cout<<"Constructor 3D Shape \n";
}
Shape3D::~Shape3D()
{
    cout<<"Destructor  3D Shape \n";
}
void Shape3D::PrintMessage()
{
    cout<<" This is 3D Shape";
}

"Sphere.h"

#ifndef SPHERE_H
#define SPHERE_H
#include <iostream>
#include "shape3d.h"
class Sphere  : public Shape3D
{
public:
    Sphere();
    ~Sphere();
    Sphere(float rs);
    float Volume();
    float Area();
    void PrintMessage();
private:
    float r;
};
#endif

"Sphere.cpp"

#include "Sphere.h"
using namespace std;
Sphere::Sphere()
{
    r=0;
}
Sphere::Sphere(float r)
{
    float rs=r;
}

Sphere::~Sphere()
{
}
float Sphere::Volume()
{
    float pi=3.14;
    return (4/3)*pi*r*r*r;
}
float Sphere::Area()
{
    float pi=3.14;
    return 4*pi*r*r;
}
void Sphere::PrintMessage()
{
    cout << "Shape type is  Sphere \n";
}

"Cube.h"

#ifndef CUBE_H
#define CUBE_H
#include <iostream>
#include "shape3d.h"
class Cube :public Shape3D
{
public:
    Cube();
    ~Cube();
    Cube(float st);
    float Volume();
    float Area();
    void PrintMessage();
private:
    float s;
};
#endif

"Cube.cpp"

#include "Cube.h"
#include <math.h>
using namespace std;

Cube::Cube()
{
    s=0;

}
Cube::Cube(float st)
{
    s=st;

}

Cube::~Cube()
{
    cout<<"Destructor  Cube \n";
}
float Cube::Volume()
{
    return s*s*s;
}
float Cube::Area()
{

    return 6*s*s;
}
void Cube::PrintMessage()
{
    cout << "Shape type is Cube";
}

Post's attachments

Без назви-2 копія.jpg 73.02 kb, 193 downloads since 2013-04-05 

2

Re: Наслідування класів!

Здається Ви поплутали змінні r та rs місцями. Мабуть, через це й такий результат.

Sphere::Sphere(float r)
{
    float rs=r;
}

Але головна проблема не в цьому. У Вас успадкування використовується просто заради успадкування. Клас Shape3D взагалі ніде не використовується (окрім успадкування).
В методі main в case 1 і case 2 майже однаковий код. Навіщо дублювати?

3

Re: Наслідування класів!

Поміняв r та rs місцями!
Результат той самий!

В методі main в case 1 і case 2 майже однаковий код. Навіщо дублювати?


Завдання таке! От і зробив!

4

Re: Наслідування класів!

1. Конструктор спрацьовує неправильно. Там не потрібно оголошувати змінну.
Просто:

Sphere::Sphere(float rs)
{
   r=rs;
}

2. Видаляти об'єкт класу потрібно просто delete, а не delete[].

3. Правильно:

int main() {
// ...
return 0;
}

У мене доречі взагалі не компілювалось

5 Востаннє редагувалося Anddep (06.04.2013 09:27:05)

Re: Наслідування класів!

Replace написав:

1. Конструктор спрацьовує неправильно. Там не потрібно оголошувати змінну.
Просто:

Sphere::Sphere(float rs)
{
   r=rs;
}

2. Видаляти об'єкт класу потрібно просто delete, а не delete[].

3. Правильно:

int main() {
// ...
return 0;
}

У мене доречі взагалі не компілювалось

1. Зробив, як Ви кажете, результат той самий(неймовірний)
2

delete[] tri;
delete [] rec;

3. Додав

int main()
...
...
...
case 3:
            {
                return 0;
            }

6

Re: Наслідування класів!

1. Функцію main() варто робити int, а не void. Скажімо, мій гцц 3.4.5 не пропустив такий раритет, як void main().
2. Anddep, для чого ви у файлах декларації класів підключаєте iostream vs namespace std? Вони вам необхідні лише у файлах реалізації класів (а там вони вами підключені явно). Підключення заголовків ув інших заголовках доцільно лише тоді, коли є:
     спадкування від класу з підключеного заголовка;
     використання змінних/полів класу деякого типу даних, визначеного в іншому заголовку;
     реалізація шаблонного класу, яка де-факто втілюється у файлах-заголовках.
Якщо вам у файлах опису класів потрібно суто згадати про тип даних з іншого файлу, користуйтеся передніми деклараціями:

Приклад
//A.h
class mytype;

class A
{
    mytype *x;
};
//A.cpp
#include "mytype.h"
#include "A.h"
A::A()
{
    x = new mytype();
}

3. Якщо ви використовуєте C++ засоби виведення, то вже не "\n", а cout<<endl застосовуйте: він має свої переваги.

7

Re: Наслідування класів!

Тут трохи з плюшками: раджу розібратися, а не просто копіпастити
#include<iostream>
using namespace std;

class Shape3D
{
public:
    Shape3D();
    virtual ~Shape3D();
    virtual float Area()=0;
    virtual float Volume()=0;
    virtual void PrintMessage();
};

Shape3D::Shape3D()
{
    cout<<"Constructor 3D Shape"<<endl;
}
Shape3D::~Shape3D()
{
    cout<<"Destructor  3D Shape"<<endl;
}
void Shape3D::PrintMessage()
{
    cout<<" This is 3D Shape";
}
/***************************/

class Sphere: public Shape3D
{
private:
    float r;
public:
    ~Sphere();
    Sphere(float /*rs*/ = 0);
    float Volume();
    float Area();
    void PrintMessage();
};

Sphere::Sphere(float rs): r(rs)
{}

Sphere::~Sphere()
{}

float Sphere::Volume()
{
    return (4.0/3)*3.14*r*r*r; /* casting to float in brackets must be definite. Otherwise, your result will be corrupted like (int)(4/3)*/
}
float Sphere::Area()
{
    return 4*3.14*r*r;
}
void Sphere::PrintMessage()
{
    cout << "Shape type is  Sphere \n";
}

/********************/

class Cube: public Shape3D
{
public:
    Cube();
    ~Cube();
    Cube(float /*st*/ = 0); 
    float Volume();
    float Area();
    void PrintMessage();
private:
    float s;
};

Cube::Cube(float st): s(st)
{}

Cube::~Cube()
{
    cout<<"Destructor  Cube \n";
}

float Cube::Volume()
{
    return s*s*s;
}

float Cube::Area()
{
    return 6*s*s;
}
void Cube::PrintMessage()
{
    cout << "Shape type is Cube";
}


int main()
{
    //setlocale(0,""); /*what's the reason to use it here?..*/
    
    float a;
    int i;
    
    while(1)
    {
        cout<<endl<<"МЕНЮ: "<<endl
            <<"1-Куб"        <<endl
            <<"2-Сфера"        <<endl
            <<"3-Вихiд:"    <<endl;
            
        cin >> i; /*Be careful: just non-digit value - and your programme flies out.*/
        
        switch(i)
        {
        case 1:
            {
                cout << "Куб:"<<endl;
                cout << "Введiть довжину ребра куба:"<<endl;
                cin >> a;
                Cube *tri;
                tri = new Cube(a);
                cout<<"Площа:" << tri->Area()<<endl<<"Об'єм:"<<tri->Volume()<<endl;
                tri->PrintMessage();
                delete tri;
                break;
            }
        case 2:
            {
                cout<< "Сфера:"<<endl;
                cout << "Введiть радiус сфери:"<<endl;
                cin >> a;
                Sphere *rec =new Sphere(a);
                cout<<endl<<"Площа поверхні:" << rec->Area()<<endl<< "Об'єм:"<<rec->Volume()<<endl;
                rec->PrintMessage();
                delete rec;
                break;
            }
        case 3:
            return 0;
        }
    }
    
    return 0;
}

8

Re: Наслідування класів!

Bartash,
Дякую, зрозумів!
Врахую!

9

Re: Наслідування класів!

Anddep написав:

Bartash,
Дякую, зрозумів!
Врахую!

Про всяк випадок - невеликий FAQ щодо прототипів функцій (зокрема, стосовно значень за замовчуванням та назв параметрів у прототипах).