有没有办法禁止转换为 C++ 中非常量的子类?

发布于 2024-07-18 21:40:13 字数 683 浏览 5 评论 0原文

这是一个完整的例子。 我想禁止使用 A::set 从 B 到 A 的对象中仅允许强制转换 B 到常量 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;
}

Here is a complete example.
I want to forbid using A::set from objects casted from B to A by allowing only casting
B to const A.
How to do it?
(I can't use virtual functions)

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空心空情空意 2024-07-25 21:40:13

为什么要铸造? 使 void A::set(int i) protected 将适用于您的情况。

Why casting? Making void A::set(int i) protected will work in your case.

酒解孤独 2024-07-25 21:40:13

您可以将继承设置为私有,并在 B 中提供一个成员函数来使用,而不是强制转换。

const A& B::convert_to_A() const { return *this; }

You could make the inheritance private and provide a member function in B to use instead of casting.

const A& B::convert_to_A() const { return *this; }
寻找一个思念的角度 2024-07-25 21:40:13

没有必要禁止非常量强制转换。 您可以使用模板方法设计模式来解决您的问题。

#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;
}

There is no need for forbidding non-const casts. You can solve your problem by using the template method design pattern.

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文