- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想在 C++ 中定义一个新类型,它只是一些原始类型(在我的示例中,int
可以是任何类型)。在此示例中,我将类型称为 NodeId
。
我可以只使用 typedef int NodeId
。我想要 NodeId
的默认值,所以我会使用 #define NULL_NODE_ID -1
。
现在,我认为定义一个类而不是 typedef
会更好,以允许函数 isValid()
和构造 null NodeId 的默认构造函数
:
class NodeId
{
int value;
public:
inline NodeId() : value(-1) {}
inline NodeId(int value) : value(value) {}
inline operator int() {return value;}
inline bool isValid() {return value != -1;}
//...
};
是否存在导致使用第二种方法的任何性能劣势?
最佳答案
实际上,这可能会变慢的原因有两个。
首先,无法创建未初始化的 NodeId。通常,这是一件好的事情。但是想象一下你有这样的代码:
NodeId nodeid;
foo.initializeNodeId(&nodeid);
你会做一个实际上没有必要的额外作业。
你可以通过添加一个特殊的构造函数来解决这个问题。创建一个 Foo::createNodeId() 可能更好,这样您就不需要 Foo::initializeNodeId(&NodeId),但是如果您不控制 Foo 的定义,那可能是不可能的。
其次,NodeId 不是编译时常量表达式。正如 dasblinkenlight 所暗示的那样,这更有可能导致代码不合法的问题,而不是导致性能问题,但两者都是可能的。 (为什么?因为如果您使用的是 int,您可能会强制编译器插入代码以在运行时执行一些本可以在编译时完成的计算。并不是说这可能是一个名为 NodeId 的类的问题...... )
幸运的是,如果您使用的是 C++11,则可以使用 constexpr 修复它。如果您希望您的代码也是合法的 C++03,您可以使用宏来处理。
此外,正如 dasblinkenlight 所指出的,您在两种方法中缺少 const。
最后,没有理由在类定义中定义的方法上写“内联”;它们本身就是内联的。
综合起来:
#if __cplusplus > 201000L
#define CONSTEXPR_ constexpr
#else
#define CONSTEXPR_
#endif
class NodeId
{
int value;
public:
struct Uninitialized {};
CONSTEXPR_ NodeId() : value(-1) {}
CONSTEXPR_ NodeId(Uninitialized) {}
CONSTEXPR_ NodeId(int value) : value(value) {}
CONSTEXPR_ operator int() const {return value;}
CONSTEXPR_ bool isValid() const {return value != -1;}
//...
};
现在您可以这样做,以避免额外的 -1 分配成本。
NodeId nodeId(NodeId::Uninitialized());
foo.initializeNodeId(&nodeid);
为了合法地使用 NodeId 作为非类型模板参数:
myClassTemplate<NodeId(3)> c;
或者,为了确保编译器可以合法地将 x 初始化为 4:
int x = 3;
x += NodeId(1);
关于c++ - 性能 : typedef vs wrapper class for primitive types?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11320004/
这只是一个练习,但我无法弄清楚其中的歧义: private static void flipFlop(String str, int i, Integer iRef) { System.out.pri
我假设 jls 中描述的转换是根据优先级排序的。首先具有更高的优先级。 jls 因此我解决了 Boxing 比 Unboxing 具有更高的优先级。我决定检验这个假设。 研究以下代码: public
我的问题看起来很简单。 int i =99999; long square = i*i; System.out.println(square); //prints 1409865409 - inc
我有一种情况,我必须更改 java 常量。 我有下面的代码工作 import java.lang.reflect.Field; import java.lang.reflect.Modifier; p
Section 4.2 of the Java Language Specification指出,“原始值不与其他原始值共享状态”。这到底是什么意思? 最佳答案 这意味着原始类型的每个值都在内存中占据
我想将对原始类型的引用传递给一个方法,这可能会改变它。 考虑以下示例: public class Main { Integer x = new Integer(42); Integer
为了学习依赖类型,我正在用 Idris 重写我的旧 Haskell 游戏。目前游戏“引擎”使用内置的整数类型,例如 Word8 .我想证明一些涉及这些数字的数字属性的引理(例如,双重否定是身份)。但是
我从react-primitives自述文件https://github.com/lelandrichardson/react-primitives#readme中读取内容,指出我们需要安装目标平台库
让我们以jackson序列化器为例,假设我们有一个这样的类: public class Car { private String brand; private Integer weig
出于某种原因,我想做这样的事情: template void write(const Data& data) { std::fstream out {...}; out.write(r
由于 C# 中的 struct 由其成员的位组成,因此您不能拥有包含任何 T 字段的值类型 T: // Struct member 'T.m_field' of type 'T' causes a c
这个问题在这里已经有了答案: Why does int i = 1024 * 1024 * 1024 * 1024 compile without error? (5 个回答) 关闭8年前。 在Jav
在好几个地方我都看到了类似这样的声明: “Scala 编译器在编译代码中尽可能使用 Java 数组、基本类型和 native 算术”(《Scala 编程》一书)。但实际上我没有看到这一点,例如在下面的
术语“同步原语”到底是什么意思?例如:互斥锁,关键部分,等待计时器,事件,监视器,条件变量,信号量。它们都是同步原语吗?我还没有列出其他同步原语吗?这些是有效的问题吗? 最佳答案 同步原语是平台(例如
我正在通读 Rubinius source code ,我不断遇到类似这样的方法: def self.do_something Rubinius.primitive :vm_do_somethin
我正在用解释器编写类似 Scheme 的程序。类似 Scheme 的解释器应该可以很好地与任何实现 IEnumerable 的对象一起工作,这似乎很自然。 解释器不允许突变 - 没有暴露有副作用的函数
ASP.NET Web Api 函数返回一个简单的 JSON 字符串。 当我从 angularjs 调用这个函数时,我得到一个带引号的字符串,而不是一个简单的字符串: return $http.pos
我正在将一个项目(不是我最初的项目)从 python2 转换为 python3。 在我的一个脚本中: sk = (key.Sub[0]/["point", ["_CM"]]).value 这适用于 p
我在一周前运行良好的应用程序中实现了指纹身份验证。没有更改代码,我现在收到以下错误: FATAL EXCEPTION: main Caused by: java.lang.IllegalSta
我在从 URL 接收 JSON 数组时遇到问题。我已经验证我的链接没问题,并且返回了正确的 JSON 数组,它甚至显示在错误消息中。我不确定这是什么意思。 错误: 04-17 21:34:04.435
我是一名优秀的程序员,十分优秀!