当编译器需要知道C(类)对象的大小时:例如,在堆栈上分配C或作为另一种类型的直接成员时
来自C++编码标准:101规则,指南和最佳实践
这是否意味着堆分配对象,大小是不是必要?
Class C;//just forward declaration
C * objc = new C();
Run Code Online (Sandbox Code Playgroud) 我如何传递指向具有私有定义的结构的指针,而不使用指针类型struct?
例如,这有效:
typedef struct Handle {
Ino ino;
} Handle;
bool handle_open(Handle **);
Run Code Online (Sandbox Code Playgroud)
但是如果我将struct定义移动到源文件中,则强制使用其他源文件struct Handle *,而不是Handle *.
我曾多次用疙瘩成语来缩短编译时间.为了得到一个"好"的头文件,我返回一个包含QPoint(一个Qt对象)指针的向量指针.
让我们看看我的头文件:
#ifndef CHEXAGON_H
#define CHEXAGON_H
class QPoint;
class QVector;
class CHexagon
{
public:
CHexagon(const unsigned int & PosX, const unsigned int & PosY, const unsigned int & Radius);
QVector * getEdges();
QPoint * getCenter();
private:
class Pimple;
Pimple * pPimple;
};
#endif // CHEXAGON_H
Run Code Online (Sandbox Code Playgroud)
它出什么问题了?
假设我有:
class B;
class A{
private:
B *b;
public:
bar(){ b->foo()};
foo();
}
class B{
private:
A *a;
public:
bar(){ a->foo();}
foo();
}
Run Code Online (Sandbox Code Playgroud)
编译时,这个文件给出了一个
错误"无效使用不完整类型struct B",
即使我已经向前声明了B类.据我所知,这是因为当我调用函数foo()时b,编译器仍然不知道存在这样的函数.我怎么解决这个问题?
这段代码炸弹:
from mongoengine import *
class Employee(Document):
name = StringField()
boss = ReferenceField("Employee", reverse_delete_rule = NULLIFY)
Run Code Online (Sandbox Code Playgroud)
以下是例外情况:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[…]/mongoengine/base.py", line 791, in __new__
new_class = super_new(cls, name, bases, attrs)
File "[…]/mongoengine/base.py", line 630, in __new__
f.document_type.register_delete_rule(new_class,
File "[…]/mongoengine/fields.py", line 757, in document_type
self.document_type_obj = get_document(self.document_type_obj)
File "[…]/mongoengine/base.py", line 136, in get_document
""".strip() % name)
mongoengine.base.NotRegistered: `Employee` has not been registered
in the document registry.
Importing the document class automatically …Run Code Online (Sandbox Code Playgroud) 最小示例"Test.h":
#import <Foundation/Foundation.h>
@protocol CallBack <NSObject>
-(void)method;
@end
@interface Test : NSObject
-(void)callback:(CallBack*)theCallback;
@end
Run Code Online (Sandbox Code Playgroud)
和相应的"Test.m":
#import "Test.h"
@implementation Test
-(void)callback:(CallBack*)theCallback
{
[theCallback method];
}
@end
Run Code Online (Sandbox Code Playgroud)
这将为.m和.h文件中的CallBack参数提供"预期类型"错误.由于CallBack协议是在其他所有内容之前定义的,所以我无法理解为什么编译器无法找到它.如果我添加一个前向定义@class CallBack; 在头文件的开头,它将给我一个"接收器类型'CallBack',例如消息是一个前向声明"行[theCallback方法]的错误.
为什么编译器找不到协议?
我知道这个问题听起来很愚蠢......我正在一个使用大量openssl库的项目中工作.我目前正在努力将使用过的库从1.0升级到1.1,这给了我很多困难.Openssl社区决定让人们不再访问其BIO,SSL,RSA,EVP_PKEY的内部结构.这似乎是一个很好的方向,但我使用这些结构有数千行代码(例如EVP_PKEY *key; key->reference = XXX;).
我注意到openssl通过前向声明隐藏这些代码(即,将公共头部分隔为公共头部+私有头部).
例如,旧结构中的代码如下所示:include/obj.h:
struct obj_st {
int property1, int property2 ....etc
}
Run Code Online (Sandbox Code Playgroud)
新结构变为include/obj.h:
struct obj_st;
Run Code Online (Sandbox Code Playgroud)
包括/ obj_private.h:
struct obj_st {
int property1, int property2 ....etc
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我将整个openssl编译为静态库.我的代码包括它#include<openssl/obj.h>不再能够访问这些属性.
处理它的一个简单方法是,我只是将所有这些私有头文件移回原始格式(没有前向声明).但这意味着每次拉新的openssl代码时我都需要这样做.
是否有任何简单的黑客攻击我可以让它们再次曝光?我想在我的代码中包含私有标头(例如#include<openssl/obj_private.h>),但许多私有标头也依赖于其他标头,结果我需要将所有标头复制到我的usr/include/openssl文件夹.我不确定这是不是一个好主意....
当使用C++ 11编译以下代码时,它的行为与预期的一样.
class Student;
class University
{
vector <Student*> students;
public:
University();
void print();
};
class Student
{
string name;
public:
Student(string nom) : name(nom) {}
friend ostream& operator << (ostream& out, Student* S)
{
return out << S -> name;
}
};
University::University()
{
for (string name: {"Alice", "Bob"})
students.push_back(new Student(name));
}
void University::print() { for (auto s: students) cout << s << '\n'; }
int main()
{
University uni;
uni.print();
}
Run Code Online (Sandbox Code Playgroud)
打印输出是
Alice
Bob
Run Code Online (Sandbox Code Playgroud)
但是,当print()函数在其类声明中实现时,如下所示:
class University
{ …Run Code Online (Sandbox Code Playgroud) 我做过这个测验,并不理解输出
#include <stdio.h>
int main()
{
void demo();
void (*fun)();
fun = demo;
(*fun)();
fun();
return 0;
}
void demo()
{
printf("GeeksQuiz ");
}
Run Code Online (Sandbox Code Playgroud)
预期:编译错误,因为我认为通常demo()需要在调用之前初始化main()?
实际结果: GeeksQuiz GeeksQuiz
我的假设是错误的,通常需要在调用它们之前定义函数吗?