因此,C++标准要求类成员按照它们在类中声明的顺序进行初始化,而不是在任何构造函数的初始化列表中提及它们的顺序.但是,这并不意味着评估这些初始化的参数的顺序.我正在使用一个经常传递对序列化对象的引用的系统,并想知道我是否可以确保以正确的顺序从中读取位,而不管这些位写入对象字段的顺序.
struct Foo {
int a;
double b;
// I want to be able to do this
Foo(SerObj &s)
: b(s.readDouble()), a(s.readInt())
{ }
// Rather than this
Foo (SerObj &s)
{
b = s.readDouble();
a = s.readInt();
}
};
Run Code Online (Sandbox Code Playgroud)
显然,重新排序ints和doubles声明中的内容并不是一件大事,但更大的对象和需要动态分配的东西有时也可以.
c++ constructor initialization operator-precedence ctor-initializer
考虑像这样的一个类:
class MyReferenceClass
{
public:
MyReferenceClass();
const double ImportantConstant1;
const double ImportantConstant2;
const double ImportantConstant3;
private:
void ComputeImportantConstants(double *out_const1, double *out_const2, double *out_const3);
}
Run Code Online (Sandbox Code Playgroud)
有一个例程(ComputeImportantConstants)在运行时计算三个常量.假设计算相当复杂,并且固有地一次产生所有三个值.此外,结果取决于构建配置,因此硬编码结果不是一种选择.
有没有一种合理的方法将这些计算值存储在类的相应const双字段中?
如果没有,你能建议一种更自然的方式在C++中声明这样的类吗?
在C#中,我会在这里使用带有静态构造函数的静态类,但这不是C++中的一个选项.我也考虑过使用非const字段或函数调用使ImportantConstant1..3,但两者都显得逊色.
我发现初始化const字段的唯一方法是使用初始化列表,但似乎不可能在这样的列表中传递多输出计算的结果.
我有一个类B需要A构造一个类的实例:
class B
{
B(A* a); // there is no default constructor
};
Run Code Online (Sandbox Code Playgroud)
现在我想创建一个包含B成员的类,所以我还需要添加A为成员并将其提供给B构造函数:
class C
{
C() : a(), b(&a) {}
A a; // 1. initialized as a()
B b; // 2. initialized as b(&a) - OK
};
Run Code Online (Sandbox Code Playgroud)
但问题是如果有人偶尔改变类中变量定义的顺序,它就会破坏
class C
{
C() : a(), b(&a) {}
B b; // 1. initialized as b(&a) while "a" uninitialized
A a; // too late...
};
Run Code Online (Sandbox Code Playgroud)
有没有一种很好的方法来解决这个问题,而无需修改类A和B …
c++ constructor initialization operator-precedence ctor-initializer
假设我有:
// MyClass.h
class MyClass
{
public:
MyClass();
private:
Something *something_;
}
// MyClass.cpp
MyClass::MyClass()
{
something_ = new Something();
}
Run Code Online (Sandbox Code Playgroud)
我应该在MyClass构造函数的构造函数初始化列表中初始化something_到NULL(或0)吗?或者这是不必要的,因为我在构造函数的主体中分配它?建议的做法是什么?
考虑以下类别:
class Foo {
int a, b;
public:
Foo() : a{1}, b{2} {} // Default ctor with member initializer list
//Foo() : a{1}, b{2} = default; // Does not work but why?
};
Run Code Online (Sandbox Code Playgroud)
(编辑:因为在几个答案中都提到了-我知道班级成员的初始化方法,但这不是重点)
我认为第二个ctor定义会更优雅,更适合现代C ++代码(另请参阅为什么=default必须明确使用默认语义时使用)。但是,似乎没有通用的编译器接受它。而cppreference对此保持沉默。
我首先想到的是,成员初始化程序列表以某种方式更改了“默认语义”,如链接的FAQ中所述,因为它可能会也可能不会默认构造成员。但是对于类内初始化器,我们将遇到同样的问题,只是这里的Foo() = default;工作很好。
那么,为什么不允许呢?
c++ default-constructor language-lawyer ctor-initializer c++11
我的理解,例如阅读本文,是派生类的构造函数不会调用其虚拟基类的构造函数。
这是我制作的一个简单示例:
class A {
protected:
A(int foo) {}
};
class B: public virtual A {
protected:
B() {}
};
class C: public virtual A {
protected:
C() {}
};
class D: public B, public C {
public:
D(int foo, int bar) :A(foo) {}
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,构造函数B::B()和C::C()正在尝试初始化A(在我的理解中,此时应该已经初始化了D):
$ g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see …Run Code Online (Sandbox Code Playgroud) 这是一个基本问题,但我很难找到明确的答案.
除了方法中的赋值之外,初始化列表是否是在C++中初始化类字段的唯一方法?
如果我使用错误的术语,这就是我的意思:
class Test
{
public:
Test(): MyField(47) { } // acceptable
int MyField;
};
class Test
{
public:
int MyField = 47; // invalid: only static const integral data members allowed
};
Run Code Online (Sandbox Code Playgroud)
编辑:特别是,有一个很好的方法来使用struct初始化器初始化struct字段吗?例如:
struct MyStruct { int Number, const char* Text };
MyStruct struct1 = {}; // acceptable: zeroed
MyStruct struct2 = { 47, "Blah" } // acceptable
class MyClass
{
MyStruct struct3 = ??? // not acceptable
};
Run Code Online (Sandbox Code Playgroud) 对于下面的C++函数:
cross(vector<int> &L_, vector<bool> &backref_, vector< vector<int> > &res_) :
L(L_), c(L.size(), 0), res(res_), backref(backref_) {
run(0);
}
Run Code Online (Sandbox Code Playgroud)
冒号(":")告诉左右两部分之间的关系是什么?可能,这段代码可以说什么呢?
考虑以下代码:
#include<iostream>
using namespace std;
class A
{
public:
A() {cout << "1";}
A(const A &obj) {cout << "2";}
};
class B: virtual A
{
public:
B() {cout << "3";}
B(const B & obj) {cout<< "4";}
};
class C: virtual A
{
public:
C() {cout << "5";}
C(const C & obj) {cout << "6";}
};
class D:B,C
{
public:
D() {cout << "7";}
D(const D & obj) {cout << "8";}
};
int main()
{
D d1;
cout << "\n";
D …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor virtual-inheritance private-inheritance ctor-initializer
我想了解为什么 C++ 标准要求虚拟基非默认构造函数不能由中间非最派生类调用,如这段代码中所示,当使用 '-D_WITH_BUG_' 编译时:
/* A virtual base's non-default constructor is NOT called UNLESS
* the MOST DERIVED class explicitly invokes it
*/
#include <type_traits>
#include <string>
#include <iostream>
class A
{
public:
int _a;
A(): _a(1)
{
std::cerr << "A() - me: " << ((void*)this) << std::endl;
}
A(int a): _a(a)
{
std::cerr << "A(a) - me:" << ((void*)this) << std::endl;
}
virtual ~A()
{
std::cerr << "~A" << ((void*)this) << std::endl;
}
};
class B: public virtual …Run Code Online (Sandbox Code Playgroud)