使用以下类定义可以改变什么来创建和销毁这些对象,并尽可能快地将它们作为函数参数传递?有一个类的原因是需要运算符重载。
班级定义:
class MyType {
int _a, _b, _c;
MyType(int a, int b, int c) : _a(a), _b(b), _c(c) {}
MyType(MyType & mt) : a(mt.a), b(mt.b), c(mt.c) {}
~MyType() {}
MyType operator+(MyType & op) {/* do something */}
}
结构定义:
struct MyTypeC {
int a; int b; int c;
};
一个程序应该在几乎相同的CPU时间运行,无论是否使用这两种类型:
void f(MyType & mt) {mt; return;}
void g(MyTypeC & mtc) {mtc; return;}
void TestCpp() {
for (int i=1e5; --i; ) {
MyType mt(0, 1, 2);
f(mt);
}
}
void TestC() {
for (int i=1e5; --i; ) {
MyTypeC mtc = {.a=0, .b=1, .c=2};
g(mtc);
}
}
即,在MyType中可以改变什么来使运行函数TestCpp()的CPU时间几乎与运行函数TestC()一样快?
编辑:
添加了MyType的成员函数的完整列表。
这些是每个相应功能的一些运行时CPU时序:
time (TestC) = 0.000618 s
time (TestCpp) = 0.001373 s
答案 0 :(得分:1)
你的问题的答案是双重的:
struct
和class
在C ++中几乎相同。默认访问对于类是私有的(这是您的代码无法编译的原因之一 - 私有构造函数);对结构公开。您可以使用与类相同的方式派生和模板以及结构。只要类代码和结构代码都相同,就没有区别。只是为了你的娱乐:如果你不愿意真正使用你的代码,那么最终的汇编程序看起来就是这样,一旦注意到,你首先就不会问这个问题:
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.00.23026.0
TITLE E:\R\playground\temp\ConsoleApplication2\ConsoleApplication2.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB OLDNAMES
EXTRN @__security_check_cookie@4:PROC
PUBLIC _main
PUBLIC ?TestC@@YAXXZ ; TestC
PUBLIC ?TestCpp@@YAXXZ ; TestCpp
PUBLIC ?g@@YAXAAUMyTypeC@@@Z ; g
PUBLIC ?f@@YAXAAVMyType@@@Z ; f
PUBLIC ??0MyType@@QAE@HHH@Z ; MyType::MyType
; Function compile flags: /Ogtp
; COMDAT ??0MyType@@QAE@HHH@Z
_TEXT SEGMENT
_a$dead$ = 8 ; size = 4
_b$dead$ = 12 ; size = 4
_c$dead$ = 16 ; size = 4
??0MyType@@QAE@HHH@Z PROC ; MyType::MyType, COMDAT
; _this$ = ecx
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 9
mov DWORD PTR [ecx], 0
mov eax, ecx
mov DWORD PTR [ecx+4], 1
mov DWORD PTR [ecx+8], 2
ret 12 ; 0000000cH
??0MyType@@QAE@HHH@Z ENDP ; MyType::MyType
_TEXT ENDS
; Function compile flags: /Ogtp
; COMDAT ?f@@YAXAAVMyType@@@Z
_TEXT SEGMENT
?f@@YAXAAVMyType@@@Z PROC ; f, COMDAT
; _mt$dead$ = ecx
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 17
ret 0
?f@@YAXAAVMyType@@@Z ENDP ; f
_TEXT ENDS
; Function compile flags: /Ogtp
; COMDAT ?g@@YAXAAUMyTypeC@@@Z
_TEXT SEGMENT
?g@@YAXAAUMyTypeC@@@Z PROC ; g, COMDAT
; _mtc$dead$ = ecx
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 18
ret 0
?g@@YAXAAUMyTypeC@@@Z ENDP ; g
_TEXT ENDS
; Function compile flags: /Ogtp
; COMDAT ?TestCpp@@YAXXZ
_TEXT SEGMENT
?TestCpp@@YAXXZ PROC ; TestCpp, COMDAT
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 25
ret 0
?TestCpp@@YAXXZ ENDP ; TestCpp
_TEXT ENDS
; Function compile flags: /Ogtp
; COMDAT ?TestC@@YAXXZ
_TEXT SEGMENT
?TestC@@YAXXZ PROC ; TestC, COMDAT
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 32
ret 0
?TestC@@YAXXZ ENDP ; TestC
_TEXT ENDS
; Function compile flags: /Ogtp
; COMDAT _main
_TEXT SEGMENT
_main PROC ; COMDAT
; File e:\r\playground\temp\consoleapplication2\consoleapplication2.cpp
; Line 37
xor eax, eax
; Line 38
ret 0
_main ENDP
_TEXT ENDS
END
生成自:
// ConsoleApplication2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class MyType {
int _a, _b, _c;
public:
MyType(int a, int b, int c) : _a(a), _b(b), _c(c) {}
MyType operator+(MyType & op) {/* do something */ }
};
struct MyTypeC {
int a; int b; int c;
};
void f(MyType & mt) { mt; return; }
void g(MyTypeC & mtc) { mtc; return; }
void TestCpp() {
for (int i = 100000; --i; ) {
MyType mt(0, 1, 2);
f(mt);
}
}
void TestC() {
for (int i = 100000; --i; ) {
MyTypeC mtc = { 0,1,2 };
g(mtc);
}
}
int main()
{
TestCpp();
TestC();
return 0;
}
答案 1 :(得分:0)
您是否观察到实际差异?除非样本中没有显示隐藏的成本,例如虚拟构造函数或方法,否则它们将生成相同的机器代码。在C ++中,struct
和class
之间唯一真正的区别是前者为成员建立了默认的public
范围,而后者建立了默认的private
范围。