Есть ли способ запретить приведение к подклассу, который не является константным в C ++? - PullRequest
0 голосов
/ 08 мая 2009

Вот полный пример. Я хочу запретить использование A :: set из объектов, приведенных из B в A, разрешив только приведение B, чтобы const A. Как это сделать? (Я не могу использовать виртуальные функции)

#include <iostream>
#include <cassert>

using namespace std;

class A {
public:
  int  get() const { return i_; }
  void set(int i) { i_ = i; }
protected:
  int i_;
};

class B : public A {
public:
  int  ok() const { return A::get() == copy_i_; }
  void set(int i) { A::set(i); copy_i_ = i; }
protected:
  int copy_i_;
};

void test2() {
  A a;
  a.set(3); // ok here
  cout << a.get() << endl;

  B b;
  b.set(5);
  A& aa = b;
  assert(b.ok());
  aa.set(3); // not ok here
  assert(b.ok()); // fail-here
}

int main() {
  test2();
  return 0;
}

Ответы [ 3 ]

2 голосов
/ 08 мая 2009

Вы можете сделать наследование частным и предоставить функцию-член в B для использования вместо приведения.

const A& B::convert_to_A() const { return *this; }
0 голосов
/ 08 мая 2009

Нет необходимости запрещать неконстантные приведения. Вы можете решить свою проблему, используя шаблон проектирования метода .

#include "stdafx.h"
#include <iostream>
#include <cassert>

using namespace std;

class A {
public:
  int  get() const { return i_; }
  void set(int i) { assert(i_ = i); copy_i();}

protected:
  int i_;
  virtual void copy_i(){};
};


class B : public A {
public:
  int  ok() const { return A::get() == copy_i_; }
protected:
  int copy_i_;
  void copy_i(){copy_i_ = i_; }
};

void test2() {
  B b;
  b.set(5);
  A& a = b;
  assert(b.ok());
  a.set(3);
  assert(b.ok()); // success!
}

int main() {
  test2();
  return 0;
}
0 голосов
/ 08 мая 2009

Почему кастинг? Защита void A :: set (int i) будет работать в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...