这是一个简化的例子来说明这个问题:
class A {};
class B
{
B(A& a) : a(a) {}
A& a;
};
class C
{
C() : b(a) {}
A a;
B b;
};
Run Code Online (Sandbox Code Playgroud)
因此B负责更新C的一部分.我通过lint运行代码并且它围绕引用成员发出错误:lint#1725.这谈到了对默认副本和分配的关注,这是公平的,但默认的副本和赋值也很糟糕,所以那里没有什么优势.
我总是尽量使用引用,因为裸指针不确定地引入了谁负责删除指针.我更喜欢按值嵌入对象,但如果我需要一个指针,我在拥有指针的类的成员数据中使用auto_ptr,并将对象作为引用传递.
当指针可能为null或可能更改时,我通常只在成员数据中使用指针.有没有其他理由更喜欢指向数据成员的引用?
是否真的可以说包含引用的对象不应该是可赋值的,因为初始化后不应更改引用?
在C++ 11之前,我们只能对整数或枚举类型的静态const成员执行类内初始化.Stroustrup在他的C++ FAQ中讨论了这个问题,给出了以下示例:
class Y {
const int c3 = 7; // error: not static
static int c4 = 7; // error: not const
static const float c5 = 7; // error: not integral
};
Run Code Online (Sandbox Code Playgroud)
以下推理:
那么为什么存在这些不方便的限制呢?类通常在头文件中声明,并且头文件通常包含在许多翻译单元中.但是,为避免复杂的链接器规则,C++要求每个对象都有唯一的定义.如果C++允许将需要作为对象存储在内存中的实体的类内定义,则该规则将被破坏.
但是,C++ 11放宽了这些限制,允许非静态成员的类内初始化(§12.6.2/ 8):
在非委托构造函数中,如果给定的非静态数据成员或基类未由mem-initializer-id指定(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer)然后,实体不是抽象类(10.4)的虚基类
- 如果实体是具有大括号或等于初始值的非静态数据成员,则按照8.5中的规定初始化该实体;
- 否则,如果实体是变体成员(9.5),则不执行初始化;
- 否则,实体默认初始化(8.5).
第9.4.2节还允许非const静态成员的类内初始化,如果它们用说明constexpr符标记的话.
那么我们在C++ 03中受到限制的原因究竟发生了什么?我们只是简单地接受"复杂的链接器规则"或者是否有其他改变使得这更容易实现?
我有一个类有几个对象作为成员变量.我不希望在声明时调用这些成员的构造函数,所以我试图明确地挂起指向该对象的指针.我不知道我在做什么.O_O
在StackOverflow上,我似乎能够找到对象成员变量的其他示例,但通常会立即调用构造函数,如下所示:
class MyClass {
public:
MyClass(int n);
private:
AnotherClass another(100); // this constructs AnotherClass right away!
};
Run Code Online (Sandbox Code Playgroud)
但我希望MyClass构造函数调用AnotherClass构造函数.这是我的代码的样子:
BigMommaClass.h
#include "ThingOne.h"
#include "ThingTwo.h"
class BigMommaClass {
public:
BigMommaClass(int numba1, int numba2);
private:
ThingOne* ThingOne;
ThingTwo* ThingTwo;
};
Run Code Online (Sandbox Code Playgroud)
BigMommaClass.cpp
#include "BigMommaClass.h"
BigMommaClass::BigMommaClass(int numba1, int numba2) {
this->ThingOne = ThingOne(100);
this->ThingTwo = ThingTwo(numba1, numba2);
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试编译时遇到的错误:
g++ -Wall -c -Iclasses -o objects/BigMommaClass.o classes/BigMommaClass.cpp
In file included from classes/BigMommaClass.cpp:1:0:
classes/BigMommaClass.h:12:8: error: declaration of âThingTwo* BigMommaClass::ThingTwoâ
classes/ThingTwo.h:1:11: error: changes …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,当X被调用的ctor 首先被调用A或被B调用时?它们放在班级正文中的顺序是否控制了这个?如果有人可以提供C++标准的一小段文本来讨论这个问题,那将是完美的.
class A {};
class B {};
class X
{
A a;
B b;
};
Run Code Online (Sandbox Code Playgroud) 以下代码不使用gcc编译,但使用Visual Studio编译:
template <typename T> class A {
public:
T foo;
};
template <typename T> class B: public A <T> {
public:
void bar() { cout << foo << endl; }
};
Run Code Online (Sandbox Code Playgroud)
我收到错误:
test.cpp:在成员函数'void B :: bar()'中:
test.cpp:11:错误:在此范围内未声明'foo'
但它应该是!如果我换bar到
void bar() { cout << this->foo << endl; }
Run Code Online (Sandbox Code Playgroud)
然后它确实编译,但我不认为我必须这样做.GCC在这里遵循C++官方规范中的某些内容,还是仅仅是一个怪癖?
我想在Python中创建一个管理所有静态成员的类.这些成员应该在课程定义期间初始化.由于以后需要重新初始化静态成员,我会将此代码放入类方法中.
我的问题:如何从班级内部调用这种类方法?
class Test():
# static member
x = None
# HERE I WOULD LOVE TO CALL SOMEHOW static_init!
# initialize static member in classmethod, so that it can be
#reinitialized later on again
@classmethod
def static_init(cls):
cls.x = 10
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏!
在此先感谢,Volker
由于此问题在这里,我想编写处理,你继承列表或集合,然后额外的属性,将其添加的情况下自定义JsonConverter.因此,一种方法是忽略所有基类属性,并仅序列化已定义类中的属性.(从技术上讲这不会起作用,因为如果你继承了那个子类,你就会破坏序列化,但它确实让我想知道......)
是否有可能通过反射(我知道答案是肯定的,因为Reflector正是如此,但我不知道如何)只获得在类本身定义的成员而不是继承的成员?例如...
public class MyBaseClass
{
public string BaseProp1 { get; set; }
public string BaseProp2 { get; set; }
}
public class MySubClass : MyBaseClass
{
public string SubProp1 { get; set; }
public string SubProp2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想反映的MySubClass,只有获得SubProp1和SubProp2而忽略BaseProp1和BaseProp2.所以,可以说是如何做呢?
中号
这是我的代码:
class Soldier {
public:
Soldier(const string &name, const Gun &gun);
string getName();
private:
Gun gun;
string name;
};
class Gun {
public:
void fire();
void load(int bullets);
int getBullets();
private:
int bullets;
}
Run Code Online (Sandbox Code Playgroud)
我需要调用Gun的所有成员函数而不是Soldier对象.就像是:
soldier.gun.fire();
Run Code Online (Sandbox Code Playgroud)
要么
soldier.getGun().load(15);
Run Code Online (Sandbox Code Playgroud)
那么哪一个是更好的设计?将枪对象隐藏为私有成员并使用getGun()函数访问它.或者让它成为公共会员?或者我可以封装所有这些函数会使实现更难:
soldier.loadGun(15); // calls Gun.load()
soldier.fire(); // calls Gun.fire()
Run Code Online (Sandbox Code Playgroud)
那么你觉得哪一个最好?
我有以下不编译的代码示例:
#include <stdio.h>
namespace my
{
class base1
{ // line 6
};
class base2: private base1
{
};
class derived: private base2
{
public:
// The following function just wants to print a pointer, nothing else!
void print(base1* pointer) {printf("%p\n", pointer);}
};
}
Run Code Online (Sandbox Code Playgroud)
gcc打印的错误是:
test.cpp:6:错误:`class my :: base1'无法访问
test.cpp:17:错误:在此上下文中
现在,我可以猜出问题是什么:在查看声明时print,编译器会看到base1并认为:base1是基类子对象derived* this,但是您无法访问它!虽然我打算这base1应该只是一个类型名称.
我怎么能在C++标准中看到这是一个正确的行为,而不是编译器中的错误(我确定它不是一个错误;我检查过的所有编译器都表现得如此)?
我该如何解决这个错误?所有以下修复工作,但我应该选择哪一个?
void print(class base1*pointer){}
void print(:: my :: base1*pointer){}
class base1; void print(base1*pointer){}
编辑:
int …Run Code Online (Sandbox Code Playgroud) 的IHideObjectMembers特技(又名IFluentInterface)可用于例如,在连贯接口实现隐藏System.Object从智能感知构件.(如果你不知道这个技巧,你可以通过上面的链接阅读它;我只是在这里重复界面的通常声明:)
using System;
using System.ComponentModel;
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IHideObjectMembers
{
[EditorBrowsable(EditorBrowsableState.Never)] bool Equals(object obj);
[EditorBrowsable(EditorBrowsableState.Never)] int GetHashCode();
[EditorBrowsable(EditorBrowsableState.Never)] Type GetType();
[EditorBrowsable(EditorBrowsableState.Never)] string ToString();
}
Run Code Online (Sandbox Code Playgroud)
我现在应该能够隐藏System.Object其他类型的成员,如下所示:
public class SomeClass : IHideObjectMembers { ... }
Run Code Online (Sandbox Code Playgroud)
要么:
public interface ISomeInterface : IHideObjectMembers { ... }
Run Code Online (Sandbox Code Playgroud)
我在VS 2008 Express和VS 2008 Standard中都试过这个.但是,根本没有成员隐藏IntelliSense.我已经EditorBrowsableAttribute在不同的项目中使用它,它总是运作良好; 但是,它在这种特定情况下不起作用.
http://i48.tinypic.com/vhb4fq.jpg
如果事情按预期发挥作用,我只会看到这种SomeMethodTwo方法.
我错过了什么吗?
PS:您可以从声明和屏幕截图中推断出我的示例代码.我有一个SomeClass叫做单个虚拟方法的类SomeMethodTwo.非常简单.我没有System.Object在这个类中重新实现这四个方法,因为这不是必需的.
class-members ×10
c++ ×7
base-class ×2
name-lookup ×2
c# ×1
c++11 ×1
class ×1
constructor ×1
filter ×1
intellisense ×1
oop ×1
python ×1
reference ×1
reflection ×1
subclass ×1
templates ×1
visibility ×1