c++从动态分配转换为引用
c++ translate from dynamic allocation to references
我有以下代码:
class A{
public:
virtual do_something() = 0;
}
class B : public A{
public:
virtual do_something() override;
}
void use_a(A *a){
if (a){
a->do_something();
delete a;
}
}
use_a( new B() );
如何将其转化为参考文献
注意,do_something()
不是const
方法。我以为它可以是这样的:
void use_a(A &&a){
a->do_something();
}
use_a( B() );
但有人告诉我,这是一种糟糕的风格,必须避免。
使用左值参考:
void use_a(A &a);
B b;
use_a(b);
或模板:
template <typename T>
void use_a(T &&a);
或者,如果它不需要是引用,则是一个智能指针:
void use_a(std::unique_ptr<A> a);
void use_a(std::shared_ptr<A> a);
很简单,您可以通过提供一个具体实例将指针转换为引用,即取消引用:
void f(int& i);
f(*(new int)); // do not do this!
问题是C++中的原始指针正是这样的——它们没有自动的生存期范围,通过转换为左值引用,您已经建议了一个约定,即实例是具体的,不应该被接收器破坏。
int* ptr = new int;
f(ptr);
delete ptr; // otherwise it leaked
现代C++使用RAII来提供受控的自动寿命管理,C++11引入了unique_ptr
和shared_ptr
来处理指针。在C++14中,我们还拥有完全避免原始指针的机制。
std::unique_ptr<int> ptr = std::make_unique<int>(/* ctor arguments here */);
f(ptr.get());
// now when ptr goes out of scope, deletion happens automatically.
另请参阅http://en.cppreference.com/w/cpp/memory/unique_ptr
在任何时候,只有一个std::unique_ptr
应该具有给定分配的地址(它承担所有权,如果不是release
d,则将delete
作为退出作用域上的分配)。
对于引用计数的指针:http://en.cppreference.com/w/cpp/memory/shared_ptr
---编辑---
根据作战人员的意见:
首先注意
Pair p = { "one", "two" };
// and
Pair p("one", "two");
Pair p{"one", "two"};
是同义的,在所有情况下,它们通过分配堆栈空间并调用Pair::Pair("one", "two")
在那里构造Pair
对象来创建堆栈局部变量p
。
但是,请记住,这是一个堆栈变量——它有一个自动生存期,将在当前作用域结束时过期。
{ Pair p{"one", "two"}; list_add(list, p); } //p is destroyed
理论上,你可以用代替它
list_add(list, Pair{"one", "two"});
但重要的是list_add
是否希望您保留该对象,直到您将其从列表中删除。。。这通常是接受指针的基于列表的函数所期望的。如果它采用一个非常数引用,它也可以这样做。
要回答您的原始帖子::
struct A { virtual void doSomething() {} };
struct B : public A { virtual void doSomething() override() {} };
void useDoSomethingInterface(A& a) {
a.doSomething();
}
int main() {
A a;
B b;
useDoSomethingInterface(a);
useDoSomethingInterface(b);
}
考虑以下内容:
void list_add(IList& list, Pair& pair) {
pair.next = list.head;
list.head = &pair; // << BAD NEWS
}
void badness(IList& list) {
list_add(list, Pair("hello", "world"));
}
void caller() {
IList list;
badness(list);
// list.head now points to a destroyed variable on the stack
C++中的C指针是原始的机器级指针。他们不算裁判。C++对象实例有一个固定的、定义良好的生存期:直到作用域结束。
但是,如果list_add
按值获取数据
void list_add(IList& list, Pair pair)
然后我们就可以了。我们创建的临时Pair必须复制一次才能创建pair
,然后再复制到列表中,这很遗憾,但至少它不会崩溃。
您的代码有点不安全。首先,如果a为null怎么办?您没有检查。
第二,如果a指向堆栈对象或数据段对象,该怎么办?你会有意想不到的行为。
如果您的对象必须动态定位,只需使用std::shared_ptr
void use_a(std::shared_ptr<A>& a){
a->do_something();
}
- 强制转换为引用类型
- 如何将 int 引用安全地转换为长引用?
- 右值引用转换后的地址更改
- C++将引用转换为指针?
- 如果可能的话,C++总是更喜欢右值引用转换运算符而不是常量左值引用吗?
- 将常量引用转换为智能指针而不复制
- 为什么不能将继承自(非模板)类 B 的实例化类模板 A 的引用转换为对 B 的引用?
- 通过 see 命令引用转换运算符
- 将项目转换为 qt5 并将未定义的引用转换为 'vtable for qt5 和 cmake
- 从 r 值引用转换为 l 值引用,为什么有效
- C++从右值引用转换为右值引用 a unique_ptr
- 将引用转换为 C++ 中的指针表示形式
- 如何正确地将引用转换为指针
- 正在将常量结构引用转换为非常量指针
- 将传递引用转换为传递返回
- 将.net引用转换为c++引用
- c++向量引用转换
- 如何将对int8_t的引用转换为对uint8_t的引用
- 如何在c++中将数字字符引用转换为Unicode
- 是否可以将对 std::list<int*> 的引用转换为对 std::list<const int*> 的引用?