我正在教一个关于面向对象编程的python类,当我正在研究如何解释类时,我看到了一个空的类定义:
class Employee:
pass
Run Code Online (Sandbox Code Playgroud)
然后,该示例继续为此类的对象定义名称和其他属性:
john = Employee()
john.full_name = "john doe"
Run Code Online (Sandbox Code Playgroud)
有趣!
我想知道是否有一种方法可以为这样的类的实例动态定义函数?就像是:
john.greet() = print 'hello world!'
Run Code Online (Sandbox Code Playgroud)
这在我的python解释器中不起作用但是有另一种方法吗?
在Effective C++一书中,我看到了以下段落:
结果,如果你写
Run Code Online (Sandbox Code Playgroud)class Empty{};它基本上和你写的一样:
Run Code Online (Sandbox Code Playgroud)class Empty { public: Empty() { ... } Empty(const Empty& rhs) { ... } ~Empty() { ... } Empty& operator=(const Empty& rhs) { ... } // copy assignment operator };以下代码将导致生成每个函数:
Run Code Online (Sandbox Code Playgroud)Empty e1; Empty e2(e1); e2 = e1;
但是在拆解通过编译上面的代码创建的可执行文件之后,我意识到并非如此:没有任何函数被调用.
这是主要的汇编代码:
00000000004006cd <main>:
4006cd: 55 push %rbp
4006ce: 48 89 e5 mov %rsp,%rbp
4006d1: b8 00 00 00 00 mov $0x0,%eax
4006d6: 5d pop %rbp
4006d7: c3 retq
Run Code Online (Sandbox Code Playgroud)
段中没有任何名为"Empty"的函数.text.
那么在我们调用构造函数或赋值空类之后,编译器的行为究竟是什么?这本书说它会产生一些功能吗?如果是这样,他们存放在哪里?
C++和Java中空类的大小是多少?为什么不是零?
sizeof();在C++的情况下返回1.
为什么在Visual C++中没有完全应用空基类优化(EBO)?
如果我有很多基类,有什么办法让我帮助编译器进行这种优化吗?
#include <iostream>
struct T1 { };
struct T2 { };
struct T3 { };
struct T4 { };
struct T5 { };
struct T6 { };
struct Test : T1, T2, T3, T4, T5, T6 { };
int main() { std::cout << sizeof(Test); } // Prints 5
Run Code Online (Sandbox Code Playgroud) #include <iostream>
class A {
public:
void foo() const {
std::cout << "const version of foo" << std::endl;
}
void foo() {
std::cout << "none const version of foo" << std::endl;
}
};
int main()
{
A a;
const A ac;
a.foo();
ac.foo();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码无法编译,你能不能告诉我为什么?
Microsoft的GDI +定义了许多在内部被视为句柄的空类.例如,(来源GdiPlusGpStubs.h)
//Approach 1
class GpGraphics {};
class GpBrush {};
class GpTexture : public GpBrush {};
class GpSolidFill : public GpBrush {};
class GpLineGradient : public GpBrush {};
class GpPathGradient : public GpBrush {};
class GpHatch : public GpBrush {};
class GpPen {};
class GpCustomLineCap {};
Run Code Online (Sandbox Code Playgroud)
还有其他两种方法来定义句柄.他们是,
//Approach 2
class BOOK; //no need to define it!
typedef BOOK *PBOOK;
typedef PBOOK HBOOK; //handle to be used internally
//Approach 3
typedef void* PVOID;
typedef PVOID HBOOK; //handle …Run Code Online (Sandbox Code Playgroud) #include <iostream>
using namespace std;
class Empty{
char omg[0];
};
int main()
{
Empty em1, em2;
Empty set[100];
cout << sizeof(Empty) << " " << sizeof(em1) << " " << sizeof(em2) << endl;
cout << (long*)&em1 << " " << (long*)&em2 << endl;
cout << "total numbers of element is: " << sizeof(set)/sizeof(*set) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它的输出是:
0 0 0
0xbff36ad0 0xbff36ac8
元素数量是:4
结果令人惊讶.
如上图所示,Empty是一个类,它的大小和它的对象都是0,为什么呢?
也许我猜,因为空类的大小是1,当类不是空时,它的大小由成员决定,但是这里的成员是特殊的,它是一个长度为0的数组,这个数组的大小是0,所以类和对象的大小都是0.
这只是我的猜测.当程序运行时,我们可以看到两个对象都有地址,地址不同.
这是我的问题:如果可以实现0大小的对象,为什么C++标准声明空对象的sizeof()= 1,它是为了"确保两个不同对象的地址不同" 为什么是大小一个空类不是零?,但现在,我们确实有不同的地址作为输出,这是怎么发生的?
而且,无论数组的大小是多少,最后一行输出总是4,为什么?
谢谢 :)
PS:我在MacOS上运行这个程序,编译器是Apple LLVM版本5.1(clang-503.0.40)(基于LLVM 3.4svn)
我有两节课:
public class HumanProperties { int prop1; int prop2; string name;}
public class Human{int age; HumanProperties properties;}
Run Code Online (Sandbox Code Playgroud)
现在,如果我想创建人类的新实例,我必须这样做Human person = new Human();
但是当我尝试访问时,我person.properties.prop1=1;在属性上有nullRefrence,因为我也必须创建新属性.我必须这样做:
Human person = new Human();
person.properties = new HumanProperties();
Run Code Online (Sandbox Code Playgroud)
现在我可以访问它 person.properties.prop1=1;
这是一个小例子,但我有从xsd生成的巨大类,我没有那么多时间手动生成这个"人"类及其所有子类.有什么方法可以通过编程方式进行,还是有一些生成器呢?
或者我可以循环遍历类并为每个属性创建新类typeof属性并将其加入父类?
谢谢!
这是给定程序的输出:
sizeof(Empty) 1
sizeof(Derived1) 1
sizeof(Derived2) 4
sizeof(Derived3) 1
sizeof(Derived4) 8
sizeof(Dummy) 1
Run Code Online (Sandbox Code Playgroud)
这是该计划:
#include <iostream>
using namespace std;
class Empty
{};
class Derived1 : public Empty
{};
class Derived2 : virtual public Empty
{};
class Derived3 : public Empty
{
char c;
};
class Derived4 : virtual public Empty
{
char c;
};
class Dummy
{
char c;
};
int main()
{
cout << "sizeof(Empty) " << sizeof(Empty) << endl;
cout << "sizeof(Derived1) " << sizeof(Derived1) << endl;
cout …Run Code Online (Sandbox Code Playgroud) 假设我有一个类型F。我知道这F是空的,但F没有默认构造函数,所以我不能F()用来构造它。有没有办法获得有效的类型对象F?我似乎记得有一次提到工会的神秘用法有这样一种方式。理想情况下,这将是constexpr友好的。
这很有用,因为无捕获 lambda 仅在 C++20 中获得了默认构造函数。在 C++17 中,如果我想“将 lambda 传递给模板”并在没有实例的情况下调用该 lambda,我需要能够从类型中重建它。
auto const f = [](int x) { return x; };
using F = decltype(f);
static_assert(std::is_empty_v<F>);
static_assert(!std::is_default_constructible_v<F>);
magically-construct-an-F(42);
Run Code Online (Sandbox Code Playgroud) empty-class ×10
c++ ×8
c# ×1
c++17 ×1
const ×1
handles ×1
java ×1
oop ×1
optimization ×1
python ×1
sizeof ×1
visual-c++ ×1