请参阅C++编码标准的规则#41 或Sutter的Gotw#70,其中指出:
使数据成员保密,除了无行为聚合(C样式结构).
为了方便起见,我经常想为这些C风格的结构添加一个简单的构造函数.例如:
struct Position
{
Position(double lat=0.0, double lon=0.0) : latitude(lat), longitude(lon) {}
double latitude;
double longitude;
};
void travelTo(Position pos) {...}
main()
{
travelTo(Position(12.34, 56.78));
}
Run Code Online (Sandbox Code Playgroud)
虽然可以更容易地动态构造Position,但构造函数也可以为我初始化默认的Position对象.
也许我可以关注std :: pair的例子并提供一个"makePosition"免费功能?NRVO应该和构造函数一样快,对吧?
Position makePosition(double lat, double lon)
{
Position p;
p.latitude = lat;
p.longitude = lon;
return p;
}
travelTo(makePosition(12.34, 56.78));
Run Code Online (Sandbox Code Playgroud)
通过添加那个可怜的小构造函数,我是否违背了"无行为聚合"概念的精神?
编辑:
是的,我知道Position p={12.34, 56.78}.但我不能travelTo({12.34, 56.78})用纯C结构.
编辑2:
对于那些对POD类型感兴趣的人:C++中的POD类型是什么?
追问: 我问一个后续问题这里是密切相关的这一个.
我有以下课程:
class Vertex {
public: float X;
float Y;
float Z;
Vertex (float first, float second, float third){
X=first;
Y=second;
Z=third;
}
};
class Obj {
vector<Vertex>vertexCoordinates;
vector<vector<int>> faces;
vector <vector<float>> faceNormals;
vector <vector<float>> faceCenters;
string objName;
int vertexCount, faceCount, edgeCount;
float maxX, minX, maxY, minY, maxZ, minZ, dx, dy, dz;
setVertexCoordinates(vector <Vertex> vertexCoordinatesP) {
vertexCoordinates = vertexCoordinatesP; //??
// How should the assignment be defined?
}
};
Run Code Online (Sandbox Code Playgroud)
我需要在这里创建一个复制构造函数吗?超负荷运营商=的Vertex和Obj?
也就是说,编译器用来生成类的标准是什么?例如,让我们说,我有类C与成员x,y以及z,我想知道的偏移z该类中.我可以只添加其他成员的数据类型大小,就像我对结构一样吗?
结构的属性是否在C++中继承
例如:
struct A {
int a;
int b;
}__attribute__((__packed__));
struct B : A {
list<int> l;
};
Run Code Online (Sandbox Code Playgroud)
struct B(struct A)的继承部分是否会继承packed属性?
我不能在没有得到编译器警告的情况下向struct B 添加一个属性((packed)):
ignoring packed attribute because of unpacked non-POD field
Run Code Online (Sandbox Code Playgroud)
所以我知道整个结构B不会打包,这在我的用例中很好,但我要求struct A的字段打包在struct B中.
我听说空的析构函数没有做任何事情,调用它不会删除对象.但在代码中:
#include <iostream>
#include <set>
class a
{
public:
~a()
{}
std::set <int> myset;
};
int main()
{
a object;
object.myset.insert(55);
object.~a();
object.myset.insert(20);
std::cout << object.myset.size();
}
Run Code Online (Sandbox Code Playgroud)
我得到:" *glibc检测到* /.app:双重免费或腐败(fasttop):"然后"ABORT".
如果重要的话我启用了c ++ 11标志.那么空构造函数实际上做了什么?它做了一些事情而我没有看过.
我对C++并不是很熟悉,当我尝试一些测试程序时,我想到了一个关于最好的问题,如果我可以这样说,在C++代码中定义一些原始元素.
我们来看一个描述矩形的类.它会创建它们,绘制它们,旋转它们,调整大小等等...现在在大多数情况下我们必须处理画布上的点.其自身的矩形由2个点描述:左上角和右下角.另外,为了旋转它,您需要一个角度和一个点(锚点).或者可能要移动它,您需要一个给定矩形的新锚点.我想我已经说明了使用积分.那么什么更有效?将此原始点定义为类还是结构?
class cPoint
{
public:
int X;
int Y;
};
Run Code Online (Sandbox Code Playgroud)
要么
typedef struct
{
int X;
int Y;
}sPoint;
Run Code Online (Sandbox Code Playgroud) 下面的代码在使用avr-g ++编译器编译时忽略了打包属性,但由于未打包的非POD字段'float&foo :: BAR',导致我遇到此错误
是什么原因?
class foo {
public:
foo(float &bar);
private:
float &BAR;
};
foo::foo(float &bar):BAR(bar)
{
}
int main()
{
float something;
foo fooobject(something);
}
Run Code Online (Sandbox Code Playgroud) 出于好奇,我用3种方式实现了vector3实用程序:array(带有typedef),类和结构
这是数组实现:
typedef float newVector3[3];
namespace vec3{
void add(const newVector3& first, const newVector3& second, newVector3& out_newVector3);
void subtract(const newVector3& first, const newVector3& second, newVector3& out_newVector3);
void dot(const newVector3& first, const newVector3& second, float& out_result);
void cross(const newVector3& first, const newVector3& second, newVector3& out_newVector3);
}
// implementations, nothing fancy...really
void add(const newVector3& first, const newVector3& second, newVector3& out_newVector3)
{
out_newVector3[0] = first[0] + second[0];
out_newVector3[1] = first[1] + second[1];
out_newVector3[2] = first[2] + second[2];
}
void subtract(const newVector3& first, const newVector3& …Run Code Online (Sandbox Code Playgroud) 这是我的代码
#include <bits/stdc++.h>
class A{
int val;
char c;
};
class B:public A{
char val;
};
struct C{
int val;
char c;
};
struct D:public C{
char val;
};
int main()
{
std::cout<<sizeof(B)<<std::endl; //8
std::cout<<sizeof(D)<<std::endl; //12
}
Run Code Online (Sandbox Code Playgroud)
为什么class有不同的对齐方式struct
*** Dumping AST Record Layout
0 | class A
0 | int val
4 | char c
| [sizeof=8, dsize=5, align=4
| nvsize=5, nvalign=4]
*** Dumping AST Record Layout
0 | class B
0 | class A (base)
0 …Run Code Online (Sandbox Code Playgroud) 我创建了一个私有API,它假定类中第一个成员对象的地址与类的this-pointer相同......这样,成员对象可以简单地派生出一个指向它的对象的指针.成员,无需显式存储指针.
鉴于我愿意确保容器类不会从任何超类继承,不会有任何虚方法,并且执行此技巧的成员对象将是第一个声明的成员对象,那个假设会保留对任何C++编译器有效,还是需要使用offsetof()运算符(或类似)来保证正确性?
换句话说,下面的代码完成了我在g ++下的期望,但它能在各处工作吗?
class MyContainer
{
public:
MyContainer() {}
~MyContainer() {} // non-virtual dtor
private:
class MyContained
{
public:
MyContained() {}
~MyContained() {}
// Given that the only place Contained objects are declared is m_contained
// (below), will this work as expected on any C++ compiler?
MyContainer * GetPointerToMyContainer()
{
return reinterpret_cast<MyContainer *>(this);
}
};
MyContained m_contained; // MUST BE FIRST MEMBER ITEM DECLARED IN MyContainer
int m_foo; // other member items may be declared after m_contained
float m_bar; …Run Code Online (Sandbox Code Playgroud) c++ ×10
struct ×2
avr ×1
casting ×1
class ×1
destructor ×1
g++ ×1
inheritance ×1
layout ×1
oop ×1
optimization ×1
padding ×1
performance ×1
physics ×1
pointers ×1
typedef ×1
types ×1
utility ×1