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

Posted

技术标签:

【中文标题】有没有办法禁止转换为 C++ 中非常量的子类?【英文标题】:Is there a way to forbid casting to subclass that is non-const in C++? 【发布时间】:2009-05-08 07:48:25 【问题描述】:

这是一个完整的例子。 我想通过只允许转换来禁止使用从 B 转换到 A 的对象的 A::set 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;

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

正是我需要的,谢谢。【参考方案2】:

为什么要选角?将 void A::set(int i) protected 设为适用于您的情况。

【讨论】:

但是我想修改纯A对象。【参考方案3】:

没有必要禁止非常量强制转换。您可以使用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;

【讨论】:

正如我所说,由于性能原因,我不能使用虚函数。如果 A 类可以保持不变,那就太好了。 在这种情况下我不认为它可以做到。但是,您是否真的分析过您的应用程序以确保虚拟功能太慢?虚函数的开销通常可以忽略不计。 我做了个人资料。虚函数太慢了,因为它们不能被内联 A::set() 中的 assert() 可能不会做你想做的事。它将在带有参数 0 的调用中被击中。

以上是关于有没有办法禁止转换为 C++ 中非常量的子类?的主要内容,如果未能解决你的问题,请参考以下文章

PyArg_ParseTupleAndKeywords 抛出警告:ISO C++ 禁止将字符串常量转换为‘char*’ [-Wwrite-strings]

有没有办法禁止我的类的子类化?

在 C++ 中将 bool 转换为文本

TensorFlow:有没有办法将冻结图转换为检查点模型?

有没有办法将犰狳矢量转换为 C++ 中的字符串?

将 C 或 C++ 常量转换为 Java