比较两个代码如下:
1 #include <new>
2 #include <cstdio>
3 class CA
4 {
5 public:
6 int i, j, k;
7 };
8
9 int main()
10 {
11 int aa[4] = { 1, 2, 3, 4 };
12 CA *i = new(aa) CA();
13 printf("%d %d %d %d\n", aa[0], aa[1], aa[2], aa[3]);
14 return 0;
15 }
1 #include <new>
2 #include <cstdio>
3 class CA
4 {
5 public:
6 int i, j, k;
7 };
8
9 int …Run Code Online (Sandbox Code Playgroud) 从这个答案来看,在C++ 03中,如果()省略了POD类型,则默认初始化,否则进行值初始化.
// POD type
struct foo {
int x;
};
// value-initialized
new foo();
Run Code Online (Sandbox Code Playgroud)
但是,如果提供了用户定义的构造函数,下面的任何对象是否会被视为默认值或值初始化?
// non-POD type
struct bar {
bar(int x = 0):x(x) {}
int x;
};
new bar();
new bar(42);
Run Code Online (Sandbox Code Playgroud) 我遇到了一些非常有趣的代码,让我想知道bool是什么.我一直认为它是一个原始类型,如int或char或long.但今天,我看到的东西看起来像这样:
void boolPtrTest()
{
bool thisBool = true;
boolPtrHere(thisBool);
printf("thisBool is %s\n", thisBool ? "true" : "false");
}
void boolPtrHere(bool& theBool)
{
theBool = false; // uhh, dereferencing anyone?
}
Run Code Online (Sandbox Code Playgroud)
这段代码运行 - 没有错误 - 并打印"thisBool是假的"!
为了进一步使这个奇怪,我运行以下代码:
bool myBool = new bool();
Run Code Online (Sandbox Code Playgroud)
......代码运行正常!
这是我的问题:什么是布尔?它是在逐个实施的基础上定义的吗?从上面显示的证据,我会说它是一个阶级.从实际角度来看(忽略上述内容),将bool定义为int/char的typedef或者将其定义为#define'd似乎也是合适的.但是,如何知道它是什么,(这将影响你如何对待它)?
编辑:我想我会补充说我在VS 2008工作.
第一:
int *p = new int;
Run Code Online (Sandbox Code Playgroud)
第二:
class A{};
A *pa = new A;
Run Code Online (Sandbox Code Playgroud)
new和编译器如何确定何时调用构造函数?在第一种情况下,编译器不生成调用p的构造函数的代码,在第二种情况下,它生成代码来调用A的构造函数.使用哪种机制进行这样的选择?
我只想在这里确认区别,以此为例:
class Gate
{
public:
Gate(); //Constructor
void some_fun();
private:
int one, two;
ptr p1;
Gate* next;
};
typedef Gate* ptr;
Gate::Gate()
{
one = 0;
two = 0;
}
void Gate::some_fun()
{
p1 = new Gate;
p1 = p1->next;
p1 = new Gate();
}
Run Code Online (Sandbox Code Playgroud)
在我的例子中,我创建了两个"Gate"的新节点,它们之间的唯一区别是第一个节点没有初始化变量"one和two",而第二个节点没有.
在我正在阅读的c ++代码中,有一些数组初始化为
int *foo = new int[length];
Run Code Online (Sandbox Code Playgroud)
还有一些像
int *foo = new int[length]();
Run Code Online (Sandbox Code Playgroud)
我的快速实验无法检测到这两者之间的任何差异,但它们彼此紧挨着使用.
有没有区别,如果有的话呢?
编辑; 因为有一个断言,第一个应该给出不确定的输出,这是一个显示可疑数量为0的测试;
[s1208067@hobgoblin testCode]$ cat arrayTest.cc
//Test how array initilization works
#include <iostream>
using namespace std;
int main(){
int length = 30;
//Without parenthsis
int * bar = new int[length];
for(int i=0; i<length; i++) cout << bar[0] << " ";
cout << endl;
//With parenthsis
int * foo = new int[length]();
for(int i=0; i<length; i++) cout << foo[0] << " ";
cout << endl;
return …Run Code Online (Sandbox Code Playgroud) 考虑这个非常简单的代码:
#include <memory>
class Foo
{
public:
Foo() {};
};
class Bar
{
public:
Bar( const std::shared_ptr<Foo>& foo ) {}
};
int main()
{
Foo* foo = new Foo;
Bar bar( std::shared_ptr<Foo>( foo ) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么Visual Studio会报告
warning C4930: 'Bar bar(std::shared_ptr<Foo>)': prototyped function not called (was a variable definition intended?)
Run Code Online (Sandbox Code Playgroud)
并且没有bar创建对象......如何将此行Bar bar( std::shared_ptr<Foo>( foo ) );解释为函数定义?
我检查了类型名称与new之后的括号吗?还有C++:警告:C4930:未调用原型函数(是一个变量定义?),但我觉得我的问题不同,因为我没有使用语法Foo()也没有Bar().
编辑:请注意,它成功编译:
Foo* foo = new Foo;
std::shared_ptr<Foo> fooPtr( …Run Code Online (Sandbox Code Playgroud) 当我从C#转换到C++时,我得到了很多建议,尽可能使用值语义.几乎可以肯定的是,如果我在任何地方发布带有指针的问题,并建议它应该是一个值.我开始看到了光,我在代码中找到了很多地方,我可以用堆栈分配的变量(通常是引用)替换动态分配和指针.所以我认为我掌握了使用堆栈分配的对象,并且当调用者中的对象生命周期比被调用者更长时,将它们作为引用传递给其他函数.
但是,当被调用者获得所有权时,我有一个关于按值传递对象的问题.请看以下示例:
class Zoo
{
void AddAnimal(Animal animal);
std::list<Animal> animals_;
}
Run Code Online (Sandbox Code Playgroud)
通常从灵活性和单元测试的角度来看,我希望Animal成为一个接口(C++中的抽象类),这样我就可以轻松地发送任意动物并通过模拟实现来模拟它.
在指针实现中,客户端代码将调用它:
Animal animal = new Lion("Bob");
myZoo.AddAnimal(animal);
Run Code Online (Sandbox Code Playgroud)
这里的客户端代码并不真正需要动物对象.它只是暂时构建它以传递给方法.所以在这种情况下,没有共享语义.所以它似乎是价值语义的一个好例子.但是,我的理解是你不能使用Animal作为值传递的参数,因为它是一个抽象类.
我的大多数不采用原始类型的成员函数都采用抽象类参数.那么处理这个问题的C++方法是什么?(那你是如何使用值语义编写C++接口的呢?)
c++ parameters abstract-class object-lifetime dynamic-allocation
为什么在运行时不能使用接口之类的抽象类。
我得到的输出:
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(615): error C2259: 'Creature' : cannot instantiate abstract class
1> due to following members:
1> 'std::string Creature::Move(std::vector<std::string,std::allocator<_Ty>> &)' : is abstract
1> with
1> [
1> _Ty=std::string
1> ]
1> visual studio 2013\projects\cpp_demo\cpp_demo\creature.h(9) : see declaration of 'Creature::Move'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(614) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=Creature
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(752) : …Run Code Online (Sandbox Code Playgroud) 我必须在C++中定义一个函数,它生成一个类Foo的向量并返回它.
我可以用不同的方式定义它,它们都是完全相同的:
C样式参数传递:
void generateFooVector(vector<Foo> * result)
{
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo> result;
generateFooVector(&result);
}
Run Code Online (Sandbox Code Playgroud)
参考传球:
void generateFooVector(vector<Foo> & result)
{
for (int i = 0; i < 100; i++)
{
Foo f = Foo();
result->push_back(f);
}
}
int main()
{
vector<Foo> result;
generateFooVector(result);
}
Run Code Online (Sandbox Code Playgroud)
实例化向量并返回指针:
vector<Foo> * generateFooVector()
{
vector<Foo> * result = new vector<Foo>();
for (int i = 0; i < …Run Code Online (Sandbox Code Playgroud)