클래서 정의와 구현 분리해서 컴파일했는데요, 컴파일시 구현 파일도 꼭 언급해야만 하는 건가요.

dltkddyd의 이미지

position.h 파일에 Position 클래스를 선언, 정의하고 position.cc 파일에 그 멤버함수를 정의했습니다. 다음과 같이요. 그런데 컴파일시 꼭

g++ -std=c++0x -o test1 test1.cc position.cc

이런 식으로 position.cc 클래스 구현파일도 언급하는 것이 올바른 컴파일 방법인지 궁금합니다. 구현파일을 직접 언급하지 않고 그냥

g++ -std=c++0x -o test1 test1.cc

라고 언급해서 컴파일을 완수할 수 있는 방법은 없을까요? 코드는 아래와 같은데, 각 파일에 내용을 올바르게 배분한 것인지도 궁금합니다.

-position.h-

#ifndef POSITION_H
#define POSITION_H
 
class Position {
private:
	int x, y;	
public:
	Position();
	Position(int _x, int _y);
	Position(const Position& right);
	virtual ~Position();
	Position& operator=(const Position& right);
	Position operator+(const Position& right);
 
 
	void setPos(int _x, int _y);
	int getX() const;
	int getY() const;
};
 
 
/*Position::Position() {
	x=0;
	y=0;
}
Position::Position(int _x, int _y) {
	x=_x;
	y=_y;
}
Position::Position(const Position& right) {
	x=right.x;
	y=right.y;
}
Position::~Position() {}
Position& Position::operator=(const Position& right) {
	x=right.x;
	y=right.y;
	return (*this);
}
 
Position Position::operator+(const Position& right) {
	return Position(x+right.x, y+right.y);
}
 
 
void Position::setPos(int _x, int _y) {
	x=_x;
	y=_y;
}
 
 
int Position::getX() const {
	return x;
}
int Position::getY() const {
	return y;
}*/
#endif

-position.cc-

#include "positoin.h"
Position::Position() {
	x=0;
	y=0;
}
Position::Position(int _x, int _y) {
	x=_x;
	y=_y;
}
Position::Position(const Position& right) {
	x=right.x;
	y=right.y;
}
Position::~Position() {}
Position& Position::operator=(const Position& right) {
	x=right.x;
	y=right.y;
	return (*this);
}
 
Position Position::operator+(const Position& right) {
	return Position(x+right.x, y+right.y);
}
 
 
void Position::setPos(int _x, int _y) {
	x=_x;
	y=_y;
}
 
 
int Position::getX() const {
	return x;
}
int Position::getY() const {
	return y;
}

-test1.cc-

#include <iostream>
using namespace std;
 
#include "position.h"
int main() {
	Position obj2(20,50);
	cout<<obj2.getX()<<"  "<<obj2.getY()<<endl;
	return 0;
}
익명 사용자의 이미지

position.h 파일에 Position 클래스를 선언, 정의하고 position.cc 파일에 그 멤버함수를 정의했습니다. 다음과 같이요. 그런데 컴파일시 꼭
 
g++ -std=c++0x -o test1 test1.cc position.cc
 
이런 식으로 position.cc 클래스 구현파일도 언급하는 것이 올바른 컴파일 방법인지 궁금합니다. 구현파일을 직접 언급하지 않고 그냥
 
g++ -std=c++0x -o test1 test1.cc
 
라고 언급해서 컴파일을 완수할 수 있는 방법은 없을까요?

gcc 사용법을 공부하세요. test1.cc 는 컴파일 하라고 알려주면서 position.cc 는 알려주지 않아도컴파일 되게 하고 싶은것 같은데, gcc 의 사용법을 공부하셔야 합니다.

코드는 아래와 같은데, 각 파일에 내용을 올바르게 배분한 것인지도 궁금합니다.

생성자(뿐만아니라 맴버함수들)의 구현이 헤더파일과 .cc 파일 양쪽에 들어가있는데, 둘 중 한 곳에만 작성하세요. 저같은 경우는 맴버함수 구현은 .cc 파일에 작성합니다.

dltkddyd의 이미지

헤더 파일에는 주석처리 이미 하고 올렸는데요. 그러면 맞게 배분한 거네요.

그리고

g++ -std=c++0x -o test1 test1.cc position.cc

위와 같이 컴파일하는 것이 잘못된 방식은 아닌거죠?

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

익명 사용자의 이미지

주석처리하신 것을 못보았네요.
위와 같은 사용법은 맞는 방법입니다.
작 은크 기프로그램 을컴파일 할때 는 종 종사용할만 한용법입니다.
큰 크기 프로그램에서는 이렇게 사용하는 것을 본적은 없습니다.

dltkddyd의 이미지

원래는 문서 구조는 다음과 같았는데요.

position.h color.h
| |
figure.h
|
test1.cc

그리고 각 문서의 내용은 다음과 같습니다.

-figure.h-

#include "color.h"
#include "position.h"
 
#ifndef FRGURE_H
#define FIGURE_H
 
//class Color;
//class Position;
class Figure {//?꾪삎??湲곕컲 ?대옒?ㅼ씠硫댁꽌 異붿긽?대옒??
public:
	//virtual ~Figure();//異붿긽?대옒?ㅼ씤?곕룄 ?뚮㈇?먮? ?좎뼵?댁빞 ?섎뒗吏€ 沅곴툑?⑸땲??  洹몃━怨??댁젣???먯썝???녿뒗 ?대옒?ㅼ뿉?쒕룄 ?뚮㈇?먮? 
 
 
	//?멸툒?댁빞 ?섎뒗吏€ 沅곴툑?⑸땲??  ?뱀떆 ???뚮㈇?먮룄 ?대윴 ?앹쑝濡??쒖닔媛€?곹븿?섏뿬???섎굹??
	//virtual void setPos(const Position& pos)=0;
	//virtual Position getPos() const=0;
	virtual void draw()=0;
	virtual void erase()=0;
	virtual void move(const Position& pos)=0;
	virtual void moveBy(const Position& deltapos)=0;
	virtual void setColor(const Color& value)=0;
	virtual Color getColor() const=0;
};
 
class Point:public Figure, public Position {
private:
	Color pColor;
public:
	Point();
	Point(const Position& _pos, const Color& _pColor);
	Point(const Point& _right);
	virtual ~Point();
 
 
	//virtual void setPos(const Positon& pos);
	//virtual Position getPos() const;
	virtual void draw();
	virtual void erase();
	virtual void move(const Position& pos);
	virtual void moveBy(const Position& deltapos);
	virtual void setColor(const Color& value);
	virtual Color getColor() const;
	// 아래와 같은 형식의 getColor 함수가 더 바람직한가요?
	//virtual const Color& getColor()
};
 
class Line:public Figure {
private:
	Position first, second;
	Color lColor;
public:
	Line();
	Line(const Position& _first, const Position& _second, const Color& _lColor);
	Line(const Line& right);
	virtual ~Line();
 
	virtual void draw();
	virtual void erase();
	virtual void move(const Position& _first, const Position& _second);//이 함수도 가상함수가 될 수 있을까요?  이 함수는
	//오버로드되나요.
 
 
	virtual void moveBy(const Position& _first, const Position& _second);
	virtual void setColor(const Color& _lColor);
	virtual Color getColor() const;
};
#endif

-figure.cc-

//#include "position.h"
//#include "color.h"
 
#include "figure.h"
#include <iostream>
using namespace std;
 
Point::Point():Figure(),Position() {}
Point::Point(const Position& _pos, const Color& _pColor):Figure(),Position(_pos), pColor(_pColor) {}
Point::Point(const Point&  _right):Figure(),Position(_right),pColor(_right.pColor) {}
Point::~Point() {}
void Point::draw() {
	cout<<"Drawing Point."<<endl;
}
void Point::erase() {
	cout<<"Eraseing Point."<<endl;
}
void Point::move(const Position& pos) {
	erase();
	Position::operator=(pos);
	draw();
}
void Point::moveBy(const Position& deltapos) {
	Position::operator=(  Position::operator+(deltapos)  );
}
void Point::setColor(const Color& value) {
	pColor=value;
}
Color Point::getColor() const {
	return pColor;
}
 
 
Line::Line():first(),second(),lColor() {}
Line::Line(const Position& _first, const Position& _second, const Color& _lColor):first(_first), second(_second), lColor(_lColor) {}
Line::Line(const Line& right):first(right.first), second(right.second),lColor(right.lColor) {}
Line::~Line() {}
 
void Line::draw() {
	cout<<"Drawing Line."<<endl;
}
void Line::erase() {
	cout<<"Erasing Line."<<endl;
}
void Line::move(const Position& _first, const Position& _second) {
	erase();
	first=_first;
	second=_second;
	draw();
}
void Line::moveBy(const Position& _first, const Position& _second) {
	erase();
	first=first+_first;
	second=second+_second;
	draw();
}
void Line::setColor(const Color& _lColor) {
	lColor=_lColor;
}
Color Line::getColor() const {
	return lColor;
}

-position.h-

#ifndef POSITION_H
#define POSITION_H
 
class Position {
private:
	int x, y;	
public:
	Position();
	Position(int _x, int _y);
	Position(const Position& right);
	virtual ~Position();
	Position& operator=(const Position& right);
	Position operator+(const Position& right);
 
 
	void setPos(int _x, int _y);
	const Position& getPos() const;
	int getX() const;
	int getY() const;
};
#endif

-position.cc-

#include "position.h"
Position::Position() {
	x=0;
	y=0;
}
Position::Position(int _x, int _y) {
	x=_x;
	y=_y;
}
Position::Position(const Position& right) {
	x=right.x;
	y=right.y;
}
Position::~Position() {}
Position& Position::operator=(const Position& right) {
	x=right.x;
	y=right.y;
	return (*this);
}
 
Position Position::operator+(const Position& right) {
	return Position(x+right.x, y+right.y);
}
 
 
void Position::setPos(int _x, int _y) {
	x=_x;
	y=_y;
}
const Position& Position::getPos() const {
	return (*this);
}
 
int Position::getX() const {
	return x;
}
int Position::getY() const {
	return y;
}

-color.h-

#ifndef COLOR_H
#define COLOR_H
 
class Color {
private:
	int red, green, blue;
public:
	Color();
	Color(int _red, int _green, int _blue);
	Color(const Color& right);
	Color& operator=(const Color&  right);
	void setRed(int _red);
	void setGreen(int _green);
	void setBlue(int _blue);
	int getRed() const;
	int getGreen() const;
	int getBlue() const;
};
#endif

-color.cc-

#include "color.h"
Color::Color():red(0), green(0), blue(0) {}
Color::Color(int _red, int _green, int _blue):red(_red), green(_green), blue(_blue) {}
Color::Color(const Color& right):red(right.red), green(right.green),blue(right.blue)  {}
Color&  Color::operator=(const Color& right) {
	red=right.red;
	green=right.green;
	blue=right.blue;
}
void Color::setRed(int _red) {
	red=_red;
}
void Color::setGreen(int _green) {
	green=_green;
}
void Color::setBlue(int _blue) {
	blue=_blue;
}
int Color::getRed() const {
	return red;
}
int Color::getGreen() const {
	return green;
}
int Color::getBlue() const {
	return blue;
}

-test1.cc-

#include <iostream>
using namespace std;
 
#include "figure.h"
int main() {
	Position obj2(20,50);
	cout<<obj2.getX()<<"  "<<obj2.getY()<<endl;
	Position obj3=obj2;
	cout<<obj2.getX()<<"  "<<obj2.getY()<<endl;
 
	Point obj4(obj3,Color(50,23,46));
 
	Position obj5=obj4.getPos();
	cout<<"  tutututtu  "<<obj5.getX()<<"  "<<obj5.getY()<<endl;
 
 
	return 0;
}

문서의 구조가 언급한 것과 같을 때에는 다음과 같이 명령을 줄 때 컴파일이 잘 됩니다.

g++ -std=c++0x -o test1 test1.cc position.cc color.cc figure.cc

그런데 Effective C++ p217~p229쪽의 내용에서는 저런 컴파일 방식이 비효율을 초래한다는 것 같은데요. 이 부분 이해가 제대로 안됩니다. 파일 인크루드 하는방법에 대해 설명을 하는 것 같은데, 명확하게 이해가 안 됩니다. 위와 같이 인크루드 하면 내용 중에 하나가 변경만 되도 전체 내용이 컴파일 되기 때문에 시간과 비용이 많이 든다. 그러니 다음과 같이 하라는 것인지요?

position.h color.h
| |
figure.cc
|
test1.cc

그리고 figure.h 파일에는 다음과 같은 전방선언을 했습니다. 바로 윗방식으로 인크루드를 사용할 때는요.

class Position;
class Color;

그런데 컴파일 하면 오류메시지가 엄청나게 출력됩니다. 컴파일이 전혀 안되고요. 이런 식으로 하면 내용이 하나 변경만해도 존체가 컴파일되는 비효율은 없을 것이다라는 내용같았는데. 제가 뭔가를 잘못 이해하고 있는 것이죠.
컴파일이 효율적으로 이루어지도록 인크루드 하는 방식이 전자 말고 다른 방식이 있다는 것으로 책의 내용을 이해했는데, 아닌가요? 전자의 방식말고 제대로 인크루드 할 수 있는 방법이 있다는 것으로 봤는데요? 왠지 제가 인크루드를 사용하는 방식에 문제가 있는 것 같습니다.

이렇게 인크루드 해도 컴파일이 되긴 하는데요.

figure.h
position.h
color.h

이 세 파일을 figure.cc에서 인크루드 합니다. 그리고

figure.h

이 파일을 color.cc 파일과 positioin.cc 파일에서 인크루두 합니다. 대신 color.cc, position.cc에 인크루드된 피일 position.h와 color.h는 주석처리해버립니다. 그리고

g++ -std=c++0x -o test1 test1.cc position.cc color.cc figure.cc

라고 컴파일 명령을 내리면 컴파일은 제대로 되는데요.
어떻게 하는 것이 제대로 된 인크루드 사용인지 모르겠습니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

익명 사용자의 이미지

g++ -std=c++0x -o test1 test1.cc position.cc color.cc figure.cc
 
그런데 Effective C++ p217~p229쪽의 내용에서는 저런 컴파일 방식이 비효율을 초래한다는 것 같은데요.
이 부분 이해가 제대로 안됩니다.
위와 같이 인크루드 하면 내용 중에 하나가 변경만 되도 전체 내용이 컴파일 되기 때문에 시간과 비용이 많이 든다.
그러니 다음과 같이 하라는 것인지요?

위 이야기에서의 얘기하는 방식은 아래처럼 하라는 이야기 입니다.

g++ -std=c++0x -c test1.cc
g++ -std=c++0x -c position.cc
g++ -std=c++0x -c color.cc
g++ -std=c++0x -c figure.cc
g++ -o test1 test1.o position.o color.o figure.o

다음과 같이 하라는 것인지요? 라고 하시면서 인크루드로 뭔가 하려고 하셨었는데, 인크루드 이야기가 아니고 컴파일러를 사용할 때 모든 소스코드를
한번에 컴파일 시키는 것은 하나의 소스코드 변경이 발생할 때 모든 소스코드를 재컴파일하게 되서 시간과 CPU 의 낭비가 되니 컴파일을 각 소프코드 별로 따로 따로 하도록 해서 소스코드의 변경 발생시 해당 소스코드만 컴파일해서 기존에 컴파일했던 다른 오브젝트들과 링크해서 새로운 바이너리를 만들 수 있는 기법을 찾으라는 의미네요. 이런 일을 Makefile 이 합니다. 이제 Makefile 을 공부하셔야 하는 것입니다. 인크루드 이야기가 아닙니다.

dltkddyd의 이미지

제가 완전히 잘못 이해를 한 것이군요. 장문의 글 봐주셔서 감사합니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.