کلاس هایی برای شبیه سازی مفاهیم اولیه هندسی مانند نقطه ، خط و چند ضلعی - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

کلاس هایی برای شبیه سازی مفاهیم اولیه هندسی مانند نقطه ، خط و چند ضلعی

+4 امتیاز

با سلام.من برنامه ای دارم که شامل سه کلاس point ,line و polygon است.من چند تا مشکل اساسی دارم.اول اینکه با وجود اینکه داخل فایل h. هر کلاس ،دو کلاس دیگه رو include میکنم ولی باز برنامه ارور میده و میگه اون کلاس رو نمی شناسه.دوم اینکه من با توجه به پارامتر های counstructor های کلاس polygon در پیاده سازی counstructor هاش مشکل دارم.لازم به ذکر است که پارامتر های تمام متدهای باید به همین شکل باشه اما من از attribute ها به خصوص کلاس polygon مطمئن نیستم.یه مشکل دیگم هم در مورد sqrt هست که با وجود اینکه math.h یا cmath رو include می کنم باز برنامه به sqrt ارور میده.و مشکل دیگم هم اینکه وقتی ما می خواهیم خروجیه یه متد اشاره گر به یه شی باشه آیا باید & اون شی رو return کنیم یا نه؟چون وقتی خود شی رو return میکنم برنامه ارور میده.من اشکالاتم رو comment کردم.می دونم خیلی طولانی شد.ولی واقعا به کمک احتیاج دارم.شرمنده.با تشکر فراوان

#pragma once
#include "line.h"
#include "polygon.h"
class point
{
private:
	int first;
	int second;
public:
	point();
	point (int x,int y);
	int pow(int);
	int getX();
	int getY();
	int distance(point* other);
	line* Line(point*);
	polygon* triangle(point*,point*);
	~point();
};
//////////////////////////////////////////////////////////////
#include "point.h"
#include "line.h"
#include "polygon.h"
#include <iostream>
using namespace std;
#include <cmath>
point::point()//defual constructor
{
	first=0;//moalefeye avale noghte
	second=0;//moalefeye dovom noghte
}
point::point (int x,int y)
	{
		first=x;
		second=y;
	}
int point::pow(int a)
{
	return a*a;
}
int point::getX(){return first;}
int point::getY(){return second;}
int point::distance(point* other)//mohasebeye faseleye point other va point jari
{
	int d= sqrt((pow(first-other->first))+(pow(second-other->second)));//chera sqrt error mide?
	return d;
}
line* point::Line(point* other)//sakhtane yek line ba estefade az do point
{
	line l(this,other);
		return &l;//aya be in shekl bayad bashe?hadaf ine ke khoroje ye esharegar be object line bashe.
}
polygon* point::triangle(point* a,point* b)//sakhtane yek mosalas ba estefade az do point pass dade shode va point jari
{
	point** tmp;
	tmp=new point*[3];
	tmp[0]=a,tmp[1]=b,tmp[2]=this;
	polygon p(tmp,3);
	return &p;
}
point::~point()
{
}
//////////////////////////////////////////////
#pragma once
#include "point.h"
#include "polygon.h"
class line
{
private:
	int m;//ship khat
	int c;//arz az mabda
public:
	line();
	line(point*,point*);
	line(int ,point*);
	bool isParallel(line*);
	bool isPrependicular(line*);
    point* intersection(line*);
    line* parallel(point*);
    polygon* triangle(line*,line*);
	~line();
};
////////////////////////////////////////////////
#include "line.h"
#include "point.h"
#include "polygon.h"
line::line()
{
	m=1;
	c=0;
}
line::line(point* a,point* b)//sakhatan khat ba do point
{
	m=((a->getY())-b->getY())/(a->getX()-b->getX());
	c=a->getY()-(m*(a->getX()));
}
line::line(int dip,point* a)//sakhtan khat ba shib va ye point
{
	m=dip;
	c=a->getY()-(dip*(a->getX()));
}
bool line:: isParallel(line* other)//check kardan tavazi do khat
{
	if(m==other->m)
     return true;
	else
	return false;
}
bool line::isPrependicular(line* other)//check kardane taamode do khat
{
	if((m*other->m)==1 || (m*other->m)==-1)
		return true;
	else
		return false;
}
point* line::intersection(line* other)//bargardandane noghteye barkhorde do khat ba farze int bodane an noghte barkhord
{
	int x=(other->c-c)/(m-other->m);
	int y=(m*x)+c;
	point p (x,y);
		return &p;
}
line* line::parallel(point* other)//sakhtane yek khat movazi ba line jari va gozarande az point other
{
	line l(m,other);
	return &l;
}
polygon* triangle(line* a,line* b)//sakhtan yek mosalas ba 3 line
{
	line** tmp;
	tmp=new line*[3];
	tmp[0]=a,tmp[1]=b,tmp[2]=this;
	polygon l(tmp,3);
	return &l;
}
line::~line()
{
}
///////////////////////////////////
#pragma once
#include "line.h"
#include "point.h"
class polygon
{
private:
	int size_of_point;
	int size_of_line;
	point** tip;//arraye e baraye save kardan raas haye yek polygon.
	line** l;//arraye e baraye save kardan zela haye yek polygon
public:
	polygon();
	polygon(point** arr,int size);//sakhtane yek polygon ba point ha.
    polygon(line** arr,int size);//sakhtane yek polygon ba line ha.
    bool isTriangle();
    bool isSquare();
	~polygon();
};
//////////////////////////////////////////////////////////////////
#include "polygon.h"
#include "line.h"
#include "point.h"
polygon::polygon()//default constructor
{
	size_of_point=0;
	size_of_line=0;
	tip=0;
	l=0;
}
polygon::polygon(point** arr,int size)//moshkel asli man.aya dorost neveshtam?moshkel asli man
{
	tip=new point*[size];
	tip=arr;
	size_of_point=size;
}
//aya in class copy coustructro ham mikhad?
polygon::polygon(line** arr,int size)//aya doroste?
{
	l=new line*[size];
	l=arr;
	size_of_line=size;
}
bool isTriangle()//check kardane mosales bodane polygon
{
	if((size_of_point==3) || (size_of_line==3))//chera zire size_of_point va size_of_line khate ghermez mikeshe?chera error mide?
		return true;
	else
		return false;
}
bool isSquare()//check kardane moraba bodane polygon
{
	if((size_of_point==4)|| (size_of_line==4))//chera zire size_of_point va size_of_line khate ghermez mikeshe?chera error mide?
		return true;
	else
		return false;
}
polygon::~polygon()//tarze sahihe distructor polygon che torie?
{
	if(tip!=0)

	{
		delete []tip;
		delete tip;
	}
	if(l!=0)
	{
		delete []l;
		delete l;
	}
}
سلام.ار وقتی که گذاشتید بسیار ممنونم.من بازم چند تا ابهام داشتم.شما داخل شماره 3 گفتید که نباید new کرد.
خب اگه new نکنیم پس چجوری به نقطه ها حافظه تخصیص بدیم.یعنی کد باید اینطوری بشه؟
 
polygon::polygon(point** arr,int size)
{
	tip=arr;
	size_of_point=size;
}

در مورد sqrt هم خطای برنامه اینه:

      IntelliSense: more than one instance of overloaded function "sqrt" matches the argument list:

تابع pow رو هم خودم تعریف کردم که یه int می گیره و توان 2 آن رو برمی گردونه.منظورتون از new کردن line در شماره 4 چیه؟من اول یه شی از line می سازم و اونو برمی گردونم.یعنی چجوری باید new کرد.به نظر شما تابع (triangle(point* a,point* b و (triangle(line* a,line* b درسته.آخه تابع دوم تو قسمت tmp[2]=this ارور داره.من  فکر می کنم counstructor های کلاس چند ضلعی کلا یه جور دیگه باید باشند که با توجه به اون دو تابع بالا نوشته می شند.به نظر شما مفهوم point ** arr در counsturctor کلاس polygon اینه که یه آرایه از چند تا point* داشته باشیم.؟یه سوال دیگه اینکه برای کلاس چند ضلعی لازمه copy coustructor هم تعریف کرد. با تشکر

 

سوال شده اسفند 24, 1392  بوسیله ی maryam (امتیاز 338)   12 33 44
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

1 پاسخ

+3 امتیاز
 
بهترین پاسخ

یک سری از اشکالات که با یک نگاه میشه دید :

۱‌ـ‌ اسم کلاس ها بهتره که با حرف بزرگ شروع بشه .

۲ـ کد شما circular dependecy داره برای رفع این مشکل این لینک رو ببینین : راه های جلوگیری از circular dependency

بهترین کاری هم که شما این جا می تونین بکنین اینه که به جای include کردن در فایل های هدر forward declaration کنید

به این شکل مثلا :

#pragma once
class line;
class polygon;
class point
{
private:
    int first;
    int second;
public:
    point();
    point (int x,int y);
    int pow(int);
    int getX();
    int getY();
    int distance(point* other);
    line* Line(point*);
    polygon* triangle(point*,point*);
    ~point();
};

 

3_ توی کد زیر نیازی به new کردن ندارین . constructor بعدی هم به همین شکل .

polygon::polygon(point** arr,int size)//moshkel asli man.aya dorost neveshtam?moshkel asli man
{
    tip=new point*[size];
    tip=arr;
    size_of_point=size;
}

۴- کد زیر هم مشکل داره  باید line رو new کنین بعد برگردونین . چون به این شکلی که نوشتین به محض خارج شدن از scope تابع line پاک میشه و خارج از تابع برنامه ارور میده  راه بهتر برای این کار می تونه این باشه :  آزاد سازی خودکار زمان برگشت از تابع

line* point::Line(point* other)//sakhtane yek line ba estefade az do point
{
    line l(this,other);
        return &l;//aya be in shekl bayad bashe?hadaf ine ke khoroje ye esharegar be object line bashe.
}

منظورم از new کردن به این شکله :

line* point::Line(point* other)//sakhtane yek line ba estefade az do point
{
    line* l=new line(this,other);
    return l;//aya be in shekl bayad bashe?hadaf ine ke khoroje ye esharegar be object line bashe.
}

 

در ضمن این جا اصلا نیازی به new کردن هم ندارین line رو با مقدار برگردونین .

 

5_ مشکل از sqrt نیست مشکل از pow هستش . ورودی pow باید ۲ تا متغیر double  باشه نه یکی .

6 _ نحوه نوشتن destructor کلاس polygon هم مشکل داره :

polygon::~polygon()//tarze sahihe distructor(emla sahiih in destructor hast albate ) polygon che torie?
{
    if(tip!=0)
 
    {
        delete []tip;
        delete tip;
    }
    if(l!=0)
    {
        delete []l;
        delete l;
    }
}

برای پاک کردن آرایه ۲ بعدی باید به این شکل عمل کنین : این لینک رو هم ببینید  آموزش آرایه ۱ بعدی و ۲ بعدی در c

polygon::~polygon()//tarze sahihe distructor polygon che torie?
{
    if(tip != NULL)
    {
        for(int i=0;i<size_of_pointes;i++)
        {
            delete[] tip[i];
        }
        delete[] tip;
    }
    // l ham be hamin shekl
}

7_ وقتی که یک تابع رو داخل کلاس به این شکل تعریف می کنین :

public:
    polygon();
    polygon(point** arr,int size);//sakhtane yek polygon ba point ha.
    polygon(line** arr,int size);//sakhtane yek polygon ba line ha.
    bool isTriangle();//..
    bool isSquare();//..
    ~polygon();
};

توی فایل cpp باید به این شکل تعریف بشه :

ا

bool isTriangle()//eshtebah 
{
    if((size_of_point==3) || (size_of_line==3))//chera zire size_of_point va size_of_line khate ghermez mikeshe?chera error mide?
        return true;
    else
        return false;
}

//dorost 

bool polygon::isTriangle()]
{
    if((size_of_point==3) || (size_of_line==3))//chera zire size_of_point va size_of_line khate ghermez mikeshe?chera error mide?
        return true;
    else
        return false;
}

 

ویرایش

شما داخل شماره 3 گفتید که نباید new کرد.

خب اگه new نکنیم پس چجوری به نقطه ها حافظه تخصیص بدیم.یعنی کد باید اینطوری بشه؟
 
polygon::polygon(point** arr,int size)
{
    tip=arr;
    size_of_point=size;
}

 

بله  به همین شکلی که نوشتید باید باشه arr رو باید قبل از صدا زدن تابع بهش حافظه بدین به این شکل :

    arr=new point*[size];
    for(int i=0;i<size;i++)
    {
        arr=new point[size];
    }

البته میتونین داخل تابع هم این کار رو بکنید ولی به نظر نمی رسه روش درستی باشه ...

راه بهتر برای این کار استفاده از vector یا list  دو بعدی  به جای ** هستش

تابع pow رو هم خودم تعریف کردم که یه int می گیره و توان 2 آن رو برمی گردونه.

تابع pow تون رو بزارید ببینم ؟ sqrt رو هم جدا تعریف کردین ؟ (البته pow داخل cmath هست نیازی به نوشتنش نیست )

به نظر شما تابع (triangle(point* a,point* b و (triangle(line* a,line* b درسته

مشکلی ندارن البته این جور نوشتن کلاس کلا صحیح نیست معنی نمیده آدم از توی کلاس point یک تابع داشته باشه  که مثلث بسازه ! بهتره کلا پاک بشه ...

به نظر شما مفهوم point ** arr در counsturctor کلاس polygon اینه که یه آرایه از چند تا point* داشته باشیم.؟

بله

یه سوال دیگه اینکه برای کلاس چند ضلعی لازمه copy coustructor هم تعریف کرد.

هر کلاسی که داخل constructor اش از new استفاده شده باید این 3 تا رو هم داشته باشه :

operator=  ,copy constructor ,destructor

پس جواب میشه بله .

 

شماره 4 رو ادیت کدم .

پاسخ داده شده اسفند 24, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد اسفند 26, 1392 بوسیله ی Ali Rahbar
من داخل سوال چند تا اشکال نوشتم.لطفا اونا رو بخونید.ممنون
به همشون جواب دادم .
شرمنده ولی من در  انتهای سوالم چند تا سوال دیگه پرسیدم که جواب ندادید.
آهان باشه ندیدم اونا رو .
ویرایش کردم
پیاده سازی تابع pow رو تو کد گذاشتم.منظورم از درست بودن تابع های  (triangle(point* a,point* b و (triangle(line* a,line* b ،درست بودن پیاده سازیشون بود.اینکه از داخل کلاس point مثلث بسازیم خواسته ی مساله است که من نقشی توش ندارم.
از forward declration که توی 2 گفتم استفاده کنین احتمالا درست میشه .
ایرادی که دارن همون برگردوندن اشاره گر هستش که توی 4 گفتم
ببخشید توی polygon مگه نباید ضلع (پاره خط) باشه؟ پس باید برای مثلث بودن اینا نقطه برخورد اضلاع رو چک کنیم ولی نمیدونم چطوری
...