我对大多数OO理论有了深刻的理解,但让我困惑的一件事是虚拟析构函数.
我认为无论什么以及链中的每个对象,析构函数总是会被调用.
你什么时候打算让它们成为虚拟的?为什么?
alloca()在堆栈上而不是在堆上分配内存,如同的情况一样malloc().所以,当我从例程返回时,内存被释放.所以,实际上这解决了我释放动态分配内存的问题.释放分配的内存malloc()是一个令人头痛的问题,如果不知何故错过会导致各种内存问题.
alloca()尽管有上述特征,为什么不鼓励使用?
在过去的几年里,我并没有非常使用过C语言.当我今天读到这个问题时,我遇到了一些我不熟悉的C语法.
显然在C99中,以下语法有效:
void foo(int n) {
int values[n]; //Declare a variable length array
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一个非常有用的功能.有没有关于将它添加到C++标准的讨论,如果是这样,为什么它被省略?
一些潜在的原因:
C++标准规定数组大小必须是常量表达式(8.3.4.1).
是的,当然我意识到在玩具示例中可以使用std::vector<int> values(m);,但这会从堆中分配内存而不是堆栈.如果我想要一个多维数组,如:
void foo(int x, int y, int z) {
int values[x][y][z]; // Declare a variable length array
}
Run Code Online (Sandbox Code Playgroud)
该vector版本变得很笨拙:
void foo(int x, int y, int z) {
vector< vector< vector<int> > > values( /* Really painful expression here. */);
}
Run Code Online (Sandbox Code Playgroud)
切片,行和列也可能遍布整个内存.
看一下comp.std.c++这个问题的讨论很明显,这个问题在争论的两个方面都有一些非常重要的名字引起争议.毫无疑问,a std::vector总是更好的解决方案.
我试图了解何时应该使用Prototype设计模式.以下是我理解的Prototype示例:
class Prototype
{
public:
virtual Prototype* clone() = 0;
...
};
class ConcretePrototype : public Prototype
{
public:
Prototype* clone() override { ... }
};
// Usage:
ConcretePrototype proto;
auto protPtr = proto.clone();
Run Code Online (Sandbox Code Playgroud)
问题在哪里:为什么这比以下更好:
class Obj
{
public:
Obj();
Obj(const Obj&);
Obj& operator = (const Obj& other);
};
Obj o;
Obj o2 = o;
Run Code Online (Sandbox Code Playgroud)
那我什么时候应该使用Prototype呢?
从boost库文档中我读到了这个:
从概念上讲,智能指针被视为拥有指向的对象,因此在不再需要时负责删除对象.
我有一个非常简单的问题:我想使用RAII作为可复制和可分配类的指针属性.
复制和赋值操作应该很深:每个对象都应该有自己的实际数据副本.此外,RTTI需要可用于属性(它们的类型也可以在运行时确定).
我应该搜索可复制智能指针的实现(数据很小,所以我不需要复制写入指针),或者我是否将复制操作委托给我的对象的复制构造函数,如本答案所示?
我可以选择哪种智能指针用于可复制和可分配的类的简单RAII?(我认为带有委托复制/赋值操作的unique_ptr到类复制构造函数和赋值运算符会做出正确的选择,但我不确定)
这是使用原始指针的问题的伪代码,它只是一个问题描述,而不是正在运行的C++代码:
// Operation interface
class ModelOperation
{
public:
virtual void operate = ();
};
// Implementation of an operation called Special
class SpecialModelOperation
:
public ModelOperation
{
private:
// Private attributes are present here in a real implementation.
public:
// Implement operation
void operate () {};
};
// All operations conform to ModelOperation interface
// These are possible operation names:
// class MoreSpecialOperation;
// …Run Code Online (Sandbox Code Playgroud) 我试图熟悉OOP概念,但不太明白它的概念virtual.
virtual destructor而不是一个virtual constructor.为什么?virtual destructors内部如何处理?我指的是连接虚析构函数说明了这个概念,但我的问题是如何将vptr两者的vtableS(派生和基地)被称为?(在虚拟成员函数的情况下,当这种情况发生时vptr,Derived类指向的函数通常只被调用)virtual destructor?任何人都可以通过链接/示例帮助我理解上述概念吗?
假设我有一个抽象类A。A 是否可以强制从它继承的任何类实现某个构造函数原型?
例如:
class A {
public:
// purely virtual function
virtual void func() = 0;
// what i would like to be able to do
virtual A(Obj) = 0;
};
Run Code Online (Sandbox Code Playgroud)
虽然上面的纯虚函数func是合法的,但构造函数A(Obj)不能是虚函数。我想B继承自的类的实例是否A将保持抽象(或一些不可实例化或错误的等价物),直到B覆盖构造函数A(Obj)。
换句话说,我想强制 的任何子类A实现一个以 anObj作为参数的构造函数。这可能吗?
如果我们没有虚拟构造函数那么为什么我们有虚拟析构函数?构造函数也可以是虚拟的吗?
可能重复:
为什么我们没有虚拟构造函数?
我知道之前已经问过这个问题,但我不理解其他答案中使用的复杂技术词汇.
我在社区上读到了构造函数不能虚拟的原因
"虚拟"机制适用于逻辑上完整(完全构造)的对象.我们知道我们使用构造函数来逻辑初始化对象.换句话说,在构造函数完成执行之前,对象尚未完全构造.因此,我们不能拥有虚拟构造函数.
有一种误解,到那时虚拟表是不完整的,所以我们不能拥有虚拟构造函数.在构造函数开始执行之前,正确构造了虚拟表,并将"this"指针传递给构造函数.而且,虚拟表机制是实现依赖的,并且在C++标准中找不到位置.因此,使用虚拟表概念争论这个问题是不合逻辑的.
现在,当构造函数完成执行任何其他函数时,可以是虚拟的.析构函数也不例外,因为它是一个函数.如果我们使用基类指针来引用派生类对象,使用它,然后删除它,则需要虚拟析构函数.如果我们有虚拟析构函数,使用'delete',从派生到基数开始调用一系列析构函数.但是,如果析构函数中没有"虚拟",则只调用基类析构函数(而不是派生类).这(可能)会在程序中产生不一致.
以上原因是否正确?答案没有谈论静态和动态类型的对象.
有没有办法通过指向base的指针复制派生类对象?或者如何创建这样的复制构造函数?
例如:
class Base {
public: Base( int x ) : x( x ) {}
private: int x;
};
class Derived1 : public Base {
public:
Derived( int z, float f ) : Base( z ), f( f ) {}
private:
float f;
};
class Derived2 : public Base {
public:
Derived( int z, string f ) : Base( z ), f( f ) {}
private:
string f;
};
void main()
{
Base * A = new *Base[2];
Base * …Run Code Online (Sandbox Code Playgroud) c++ ×9
constructor ×4
inheritance ×2
polymorphism ×2
virtual ×2
alloca ×1
allocation ×1
arrays ×1
base-class ×1
c ×1
gcc ×1
malloc ×1
oop ×1
shared-ptr ×1
stack ×1
standards ×1