c++ 클래스 디자인 질문입니다.

kaeri17의 이미지

안녕하세요. 간단한 계산 프로그램을 짜고 있는데 C++클래스 디자인이 생각처럼 잘 안되서 질문드립니다. 먼저 다음과 같은 행렬 클래스가 있습니다.

class Matrix
{
private:
....
public:
    VectorView row(int n);
    VectorView column(int n);
]

제가 하고싶은 일은 이 VectorView클래스를 잘 만들어보고싶은 건데요, 이 VectorView는 1차원 vector와 비슷한데, 별도의 저장공간 대신에 Matrix의 데이터에 직접 접근하게 만들고 싶습니다. iterator와 비슷하다고 할수 있죠.

근데 문제는 뭐냐면, 이 VectorView를 이용하는 함수를 만들때 입니다.

void myFunc(VectorView& v);

이 함수는 VectorView에 어떤 연산을 해 주는 함수입니다. 또한 VectorView의 경우 내부에 data포인터 말고도 크기라던지 여러가지 데이터가 부가적으로 있기 때문에 되도록이면 복사를 해서 쓰고싶지 않습니다. 그래서 이렇게 참조로 받게 함수를 만들었습니다. 이 함수를 다음과 같이 쓰면 Matrix m의 행에 어떤 연산을 하겠다는 것이죠.

Matrix m;
...
myFunc(m.row(n));

근데 문제는, 이 m.row()는 임시객체를 반환하고 그때문에 이 함수 실행은 컴파일 에러를 내게 됩니다. 임시객체의 참조값을 이용하려 했다는 것이죠. 제 생각에 이걸 어떻게 해결할수 있는 좋은 방법이 있을 것 같은데 잘 모르겠습니다. 혹여나 좋은 방법이 생각나시면 알려주시면 감사하겠습니다.

klara의 이미지

말씀하신대로 iterator같은 성격을 가진다면 iterator의 구현을 참고하면 되겠죠.

kid1402의 이미지

Matric 클래스를 조금 수정하시면 될거같네요.

일단 원래 row() 함수는 좀더 의미를 명확하게, '상수 임시객체를 반환해서 읽기 작업만 가능하게 하겠다'라고 하시면

public :
    const VectorView row(int n);

으로 선언하시고,
실제 row() 값을 변환할 수 있게 하시려면 해당 row() 함수가 VectorView의 포인터를 반환하도록 해서, void myFunc() 함수가 포인터를 통해 접근하게 하시면 될듯

아니면 아예, row() 함수 자체가 읽기/쓰기 기능이 둘다 가능하도록

public :
    VectorView& row(int n);

와 같이 레퍼런스를 반환하게 하면 될거 같네요
kaeri17의 이미지

C++에서는 포인터 같은 객체와 컨테이너 같은 객체를 명확히 구분합니다. 포인터 같은 객체(예를들어 iterator)는 기본적으로 참조형으로 받는것에 대해서 생각하지 않고, 컨테이너는 함수의 인자를 기본적으로 참조형으로 받는것으로 생각합니다. 또한 const의 의미도 다른데요, 컨테이너에 대한 const는 컨테이너 내부 객체를 변경할수 없다는 것이고, 이터레이터에 대한 const는 해당 이터레이터 값을 변경할 수 없다는 것이죠. 그래서 내부객체를 const로 이용하려면 const_iterator같은것을 써야하는 것이고요. 제 경우는 VectorView를 컨테이너처럼도 함수 인자를 받길 원하면서 iterator처럼도 행동하기를 원했기 때문에 이 문제가 생겼습니다. VectorView크기가 좀 되긴 하지만, 약간의 overhead를 감수하고 그냥 참조로 받는 부분을 없앴습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.