2017-11-28 16 views
-6

실린더 클래스가 인쇄 및 볼륨 기능을 제대로 수행하지 못하는 것 같습니다. 다음은 할당에 대한 지침입니다. 추상 기본 클래스 인 Shape라는 클래스를 디자인하십시오. Shape에는 두 개의 순수 가상 함수 인 printShapeName과 print가 있습니다.가상 함수 "Shape"Assign

셰이프에는 두 개의 다른 가상 함수, 영역 및 볼륨이 있으며 각 영역에는 0 값을 반환하는 기본 구현이 있습니다.

Point 클래스는 Shape의 이러한 구현을 상속합니다 (점의 면적과 부피는 모두 0 임). Point는 x와 y 좌표 private 멤버를가집니다.

클래스 원은 공개 상속을 사용하는 Point에서 파생됩니다. Circle의 볼륨은 0.0이므로 기본 클래스 멤버 함수 볼륨은 무시되지 않습니다. 서클에는 0이 아닌 영역이 있으므로이 클래스에서 영역 함수가 재정의됩니다. 돌아오고 Circle에 새로운 반지름을 할당하는 get 및 set 함수를 작성하십시오.

클래스 실린더는 공개 상속을 통해 Circle에서 파생됩니다. Cylinder에는 Circle과 다른 면적과 부피가 있으므로이 클래스에서는 면적 및 부피 함수가 모두 재정의됩니다. get 및 set 함수를 작성하여 높이를 반환하고 새 높이를 지정하십시오.

한 점, 한 원 및 한 원을 작성한 다음 결과를 인쇄하십시오.

// 
// Shape.hpp 
// HW6_VirtualFunctions 
// 
// Created by Aviv Fedida on 11/25/17. 
// Copyright © 2017 Aviv Fedida. All rights reserved. 
// 

#ifndef Shape_hpp 
#define Shape_hpp 

#include <stdio.h> 
#include <iostream> 
#include <cmath> 
using namespace std; 

class Shape { 
protected: // protected members 
    double width, height, radius, pi, x, y; 
public: 
    void setWidth(double a); // prototype for width setter 
    void setHeight(double b); // prototype for height setter 
    void setX(double c); 
    void setY(double d); 
    void setRad(double r); 
    void setPi(double p); 
    double getWidth() { // get width to return only 
     return width; 
    } 
    double getHeight() { // get height to return only 
     return height; 
    } 
    double getX() { 
     return x; 
    } 
    double getY() { 
     return y; 
    } 
    double getRad() { 
     return radius; 
    } 
    double getPi() { 
     return pi; 
    } 
    // Create public virtual functions 
    virtual void printShapeName() = 0; // pure virtual for printing shape's name 
    virtual void print(double a, double b) = 0; // pure virtual print function 
    virtual double area() { // virtual area function returns default null 
     return 0; 
    } 
    virtual double volume() { // virtual default volume function returns null 
     return 0; 
    } 
}; // END BASE CLASS ------------------------------------------------------------------------------------- 

class Point: public Shape { 
    // x & y coordinates needed for a point 
public: 
    // Prototypes for print & set functions 
    void printShapeName(); 
    void print(double a, double b); 
    }; // end first derived class ------------------------------------------------------------------------ 

class Circle: public Point { 
public: 
    // Protoypes for print functions 
    void printShapeName(); 
    void print(double r, double p); 
    // Prototypes for area & volume functions 
    double area(double r, double p); 
}; // end second derived class ---------------------------------------------------------------------------- 

class Cylinder: public Circle { 
public: 
    double area(double r, double p); 
    void printShapeName(); 
    double volume(double r, double p, double h); 
    void print(double r, double p, double h); 
}; // end third and final derived class -------------------------------------------------------------------------- 

// Some definitions outside classes 
//-------------------------------------------------- BEGIN ----------------------------------------------------------- 
// Shape base class setter functions defined 
void Shape::setWidth(double a) { 
    width = a; 
} 
void Shape::setHeight(double b) { 
    height = b; 
} 
void Shape::setX(double c) { 
    x = c; 
} 
void Shape::setY(double d) { 
    y = d; 
} 
void Shape::setRad(double r) { 
    radius = r; 
} 
void Shape::setPi(double p) { 
    p = 3.1416; 
    pi = p; 
} 

void Point::printShapeName() { // Print name of class 
    cout << "Point " << endl; 
} 
void Point::print(double a, double b) { // Print values within class 
    cout << "(" << a << "," << b << ")" << endl; 
} 

void Circle::printShapeName() { 
    cout << "Circle " << endl; 
} 
// Circle area function defined 
double Circle::area(double r, double p) { 
    double area; 
    area = p*(pow(r,2)); 
    return area; 
} 
void Circle::print(double r, double p) { 
    cout << "Area of circle is: " << area(r, p) << endl; 
    cout << "Volume of circle is: " << volume() << endl; 
} 

void Cylinder::printShapeName() { 
    cout << "Cylinder " << endl; 
} 
double Cylinder::area(double r, double p) { 
    double area; 
    area = 2*p*r; 
    return area; 
} 
double Cylinder::volume(double r, double p, double h) { 
    double volume; 
    volume = p*(pow(r,2))*h; 
    return volume; 
} 
void Cylinder::print(double r, double p, double h) { 
    cout << "Area of cylinder is: " << area(r, p) << endl; 
    cout << "Volume of cylinder is: " << volume(r, p, h) << endl; 
} 



#endif /* Shape_hpp */ 

// 
// main.cpp 

#include <iostream> 
#include "Shape.hpp" 
#include "Shape.cpp" 

using namespace std; 

int main() { 
    double pi = 3.1416; // Variable for pi 
    // Instantiate class objects 
    Point guard; 
    Circle k; 
    Cylinder cid; 
    // Instantiate pointers to class objects 
    Shape *pptr; 
    Shape *kptr; 
    Shape *cptr; 
    // Assign memory of objects to pointer variables 
    pptr = &guard; 
    kptr = &k; 
    cptr = &cid; 
    // Call objects via pointers and print members 
    pptr->printShapeName(); 
    pptr->print(5,6); 
    cout << '\n'; 
    kptr->printShapeName(); 
    kptr->print(9,pi); 
    cout << '\n'; 
    cptr->printShapeName(); 
    cptr->getHeight(); 
    cptr->setHeight(8); 
    cptr->print(5,pi); 
    return 0; 
} 

Cylinder 클래스의 인쇄 기능에 세 번째 높이 인수를 추가하려고하면 오류가 발생합니다. 그것은 내 서클 클래스 정의를 사용하여 끝납니다.

+1

"PLEASE ASSIST"여기가 중요합니다. "실린더 클래스에서 인쇄 및 볼륨 기능을 제대로 수행 할 수 없습니다." 무슨 일 이니? 귀하와 답변자가 문제가 무엇인지 알 때 대답은 항상 더 좋습니다. – user4581301

+1

나는 이것을 강력히 추천한다 :'#include "Shape.cpp"'. 헤더 파일을 포함하십시오. 구현 파일을 컴파일하고 링크하십시오. IDE가 자신이해야 할 일을하고이 파일을 컴파일 및 링크하여 링커 오류가 발생하게 할 수 있습니다. 우리는 당신의 문제가 무엇인지 모른다. 아니면 아닐 수도 있습니다. – user4581301

+0

OO 프로그램을 올바르게 구현하지 않습니다. 오류가 아니라 오류와 연결될 가능성이 큽니다. –

답변

0

아직 답변을 찾지 못한 경우 cptr->print(5,pi);은 2 개의 매개 변수를 사용하여 print으로 전화합니다. Circle에는 2 파라미터 printCylinder이 있으며 3 파라미터 print을가집니다. Cylinderprint의 두 매개 변수를 상속하므로 Circle 인 것처럼 CylinderCircle 인 것처럼 인쇄됩니다.

JakeFreeman의 의견은 도움이되지 않을 수도 있지만 정확하게 맞습니다. 시도하고 당신의 교과서의 몇 장을 반복하지 않고 도움이되도록합시다.

캡슐화와 polymprphism의 두 가지 주요 OO 개념을 실행했습니다.

여기서 캡슐화가 주요한 문제이며,이 문제를 해결하면 다형성 문제를 해결할 수 있습니다.

Cylinder 개체는 하나의 실린더를 나타냅니다. 그 안에 반경과 높이가 있어야합니다. 함수를 호출하고 반지름과 높이를 전달하는 것은 이데올로기 적으로 잘못된 것입니다. Cylinder에서 메서드를 실행하면 해당 반경과 높이를 이미 알고 있어야합니다. volume 메서드는 매개 변수를 사용하지 않아야합니다. 볼륨을 계산하는 데 필요한 모든 것이 이미 알려져 있어야하기 때문입니다. 이렇게하면 인터페이스를 뒷받침하는 방법이 모양마다 다를지라도 모든 모양이 동일한 volume 인터페이스를 가질 수 있습니다.

정확히 같은 논리가 영역에 적용됩니다.

다음으로 모든 모양에 반경이있는 것은 아니므로 Shape은 반경에 대해 알 필요가 없습니다. 또는 높이. 또는 깊이. 어쩌면 셰이프가 앵커 포인트를 알고있을 수도 있지만, 셰이프가 알아야 할 것이 전부입니다.

마찬가지로 print에는 IO 스트림이 일반적으로 실린더가 알거나 충분히 포함 할 것으로 기대하는 것이 아니기 때문에 인쇄 할 IO 스트림에 대한 참조를 제외하고 매개 변수가 필요하지 않습니다.

1 개의 nag : 왜 pi를 모두 지나치나요? 파이가 상수가 아닌 시스템을 가지고 있다면, 당신은 기괴한 시스템을 가지고 있습니다.

개정 된 모양 :

class Shape { 
protected: // protected members 
    static constexpr double pi = 3.1459 // add more precision as needed 
    double x, y; 
public: 
    Shape (double posx, double posy): x(posx), y(posy) 
    { // set up as much as you can in a constructor because otherwise you always 
     // have to look over your shoulder and test, "Did the object get properly 
     // initialized?" 
    } 
    void setX(double c) 
    { 
     if (c is within logical bounds) 
     { // because a setter that does not protect the object is no better for 
      encapsulation than a public member variable 
      x = c; 
     } 
    } 
    void setY(double d); 
    { 
     if (d is within logical bounds) 
     { 
      x = d; 
     } 
    } 
    double getX() { 
     return x; 
    } 
    double getY() { 
     return y; 
    } 
    // Create public virtual functions 
    virtual void printShapeName() = 0; // pure virtual for printing shape's name 
    virtual void print() = 0; // pure virtual print function 
    virtual double area() { // virtual area function returns default null 
     return 0; 
    } 
    virtual double volume() { // virtual default volume function returns null 
     return 0; 
    } 
}; 

주 형태의 베어 뼈 지사 아무것도 설정 없음. 광장에 setRadius 함수를 강제로 그냥 바보입니다.

Point의 필요성을 제거하지만 이는 좋은 방법입니다. 원이 포인트 유형입니까? 아닙니다. 원은 한 지점입니다. 매우 드문 경우를 제외하고는 is-a 관계가없는 한 확장하지 마십시오. 사각형은 특수화 된 사각형입니다. 사각형은 특수한 모양입니다. 하지만 어느 것도 요점이 아닙니다.

setXsetY을 모두 으로 그룹화하는 것이 좋습니다.이 두 작업은 나중에 원자력 거래로 전환하기가 더 쉽기 때문에 동시에 수행됩니다.

Circle 개정 :

class Circle: public Shape { 
protected: 
    double radius; 
public: 
    Circle(double posx, double posy, double rad): Shape(posx, posy), radius(rad) 
    { 
    } 
    void setRadius(double rad) 
    { 
     if (rad makes sense) 
     { 
      radius = rad; 
     } 
    } 
    double getRadius() 
    { 
     return radius; 
    } 
    // Protoypes for print functions 
    void printShapeName(); 
    virtual void print(); 
    double area(); 
}; 

double Circle::area() { 
    return pi*radius*radius; // note on pow. It can be very slow. For simple 
           // exponents just multiply 
} 
void Circle::print() { 
    cout << "Area of circle is: " << area() << '\n'; 
    // also shy away from `endl` in favour of a raw end of line. 
    // endl flushes the stream to the underlying media, also very expensive, 
    // so something best done when you have to or you have nothing better to do. 
    cout << "Volume of circle is: 0\n"; 
} 

CircleShape에 추가 할 필요가 무엇을 추가합니다. 아무것도 더. 아무것도 덜합니다. Cylinder도 마찬가지입니다. 이 원 플러스 height, height 대한 접근, Circlearea 방법 height, 표면적을 계산 자체 area 방법을 이용하여 체적 계산하고, 그 통계

추가 정보를 출력 다른 인쇄 방법이다 : 귀하의 컴파일러가 지원하고, 이번에는 override 키워드를 활용해야합니다. 컴파일러가 override라고 표시된 메소드를 찾았고 아무 것도 오버라이드하지 않으면 디버깅이 아니라 깨끗한 에러 메시지를 얻습니다.