我有时会使用大括号来隔离代码块,以避免以后错误地使用变量.例如,当我SqlCommand在同一个方法中放入几个s时,我经常复制粘贴代码块,最后混合名称并执行两次命令.添加大括号有助于避免这种情况,因为SqlCommand在错误的位置使用错误将导致错误.这是一个例子:
Collection<string> existingCategories = new Collection<string>();
// Here a beginning of a block
{
SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction);
getCategories.Parameters.AddWithValue("@sourceId", sourceId);
using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult))
{
while (categoriesReader.Read())
{
existingCategories.Add(categoriesReader["Title"].ToString());
}
}
}
if (!existingCategories.Contains(newCategory))
{
SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction);
// Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not …Run Code Online (Sandbox Code Playgroud) 假设我有如下代码:
int Main()
{
if (true)
{
new Thread(()=>
{
doSomeLengthyOperation();
}).Start();
}
while (true)
{
//do nothing
}
}
Run Code Online (Sandbox Code Playgroud)
有2个线程,我会打电话给主线程正在执行main()函数的线程,该线程被new'ed了里面的"如果"测试为主题A.
我的问题是,线程A什么时候被销毁?do doSomeLenghtyOperation()能够完成吗?
由于没有指向线程A的引用,它是否会被标记为垃圾收集的候选者:
我看到的所有示例都是Main()持有引用,然后主线程在退出之前等待与线程A连接.我很好奇上面代码的生命周期是什么.
提前致谢!
已经建立(见下文)new创建对象需要放置
int* p = (int*)malloc(sizeof(int));
*p = 42; // illegal, there isn't an int
Run Code Online (Sandbox Code Playgroud)
然而,这是在C中创建对象的一种非常标准的方式.
问题是,int如果是在C中创建并返回到C++ ,是否存在?
换句话说,以下是否保证合法?假设intC和C++是相同的.
foo.h中
#ifdef __cplusplus
extern "C" {
#endif
int* foo(void);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
foo.c的
#include "foo.h"
#include <stdlib.h>
int* foo(void) {
return malloc(sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "foo.h"
#include<cstdlib>
int main() {
int* p = foo();
*p = 42;
std::free(p);
}
Run Code Online (Sandbox Code Playgroud)
有关安置强制性质的讨论的链接new:
这是对我之前问题的后续跟踪功能参数的破坏顺序是什么?因为我不小心把参数与参数混淆了 感谢Columbo和TC在该问题的评论中清除术语混淆.
如果某些函数的主体f带有参数p_1,...,p_n类型T_1,......,T_n分别抛出异常,完成或返回,参数被破坏的顺序是什么?为什么?如果可能,请提供标准参考.
例子:
template <typename ... Args>
void f(Args ... params) {} // in what order are params destroyed?
void f(T1 p1, T2 p2, T3 p3) {} // in what order are p1, p2 and p3 destroyed?
Run Code Online (Sandbox Code Playgroud) 在过去的两年里,我一直在我的项目中广泛使用智能指针(boost :: shared_ptr).我理解并欣赏他们的好处,我一般都喜欢他们.但是我越是使用它们,我就越想念C++的确定性行为,关于内存管理和RAII,我似乎更喜欢编程语言.智能指针简化了内存管理的过程并提供了自动垃圾收集等功能,但问题是一般使用自动垃圾收集和智能指针特别引入了(de)初始化顺序的某种程度的不确定性.这种不确定性使控制权远离程序员,并且正如我最近意识到的那样,它完成了设计和开发API的工作,
为了详细说明,我目前正在开发一个API.此API的某些部分要求在其他对象之前初始化或销毁某些对象.换句话说,(de)初始化的顺序有时很重要.举个简单的例子,假设我们有一个名为System的类.系统提供一些基本功能(在我们的示例中记录)并通过智能指针保存许多子系统.
class System {
public:
boost::shared_ptr< Subsystem > GetSubsystem( unsigned int index ) {
assert( index < mSubsystems.size() );
return mSubsystems[ index ];
}
void LogMessage( const std::string& message ) {
std::cout << message << std::endl;
}
private:
typedef std::vector< boost::shared_ptr< Subsystem > > SubsystemList;
SubsystemList mSubsystems;
};
class Subsystem {
public:
Subsystem( System* pParentSystem )
: mpParentSystem( pParentSystem ) {
}
~Subsystem() {
pParentSubsystem->LogMessage( "Destroying..." );
// Destroy this subsystem: deallocate memory, release resource, etc.
} …Run Code Online (Sandbox Code Playgroud) 根据此答案,IOptionsMonitor将以单例形式注册在DI容器中,并且能够通过OnChange事件订阅来检测更改。它有一个CurrentValue属性。
另一方面,通过读取每个请求的最后一个选项IOptionsSnapshot被注册为作用域,并且还具有更改检测功能,但是它没有OnChange事件。它有一个Value属性。
例如,将两者都注入到视图中将为我们提供完全相同的行为:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Options;
using UsingOptionsSample.Models;
using UsingOptionsSample.Services;
namespace UsingOptionsSample.Pages
{
public class MyOptions
{
public MyOptions()
{
// Set default value.
Option1 = "value1_from_ctor";
}
public string Option1 { get; set; }
public int Option2 { get; set; } = 5;
}
public class OptionsTestModel : PageModel
{
private readonly MyOptions _snapshotOptions;
private readonly MyOptions _monitorOptions;
public OptionsTestModel( …Run Code Online (Sandbox Code Playgroud) dependency-injection interface options object-lifetime asp.net-core
根据C ++ 17 [basic.compound] / 3:
指针类型的每个值都是以下之一:
- 指向对象或函数的指针(据说该指针指向对象或函数),或
- 一个超出对象末尾的指针(8.7),或者
- 该类型的空指针值(7.11),或者
- 无效的指针值。
该malloc函数返回一个指针值。让我们假设调用成功,因此返回值不为null。malloc([c.malloc])的规范没有声明它在返回的存储中创建了任何对象,因此似乎“无效的指针值”是最没有意义的类别。
在Java中:
class Base {
public Base() { System.out.println("Base::Base()"); virt(); }
void virt() { System.out.println("Base::virt()"); }
}
class Derived extends Base {
public Derived() { System.out.println("Derived::Derived()"); virt(); }
void virt() { System.out.println("Derived::virt()"); }
}
public class Main {
public static void main(String[] args) {
new Derived();
}
}
Run Code Online (Sandbox Code Playgroud)
这将输出
Base::Base()
Derived::virt()
Derived::Derived()
Derived::virt()
Run Code Online (Sandbox Code Playgroud)
但是,在C++中,结果是不同的:
Base::Base()
Base::virt() // ? Not Derived::virt()
Derived::Derived()
Derived::virt()
Run Code Online (Sandbox Code Playgroud)
(有关C++代码,请参阅http://www.parashift.com/c++-faq-lite/calling-virtuals-from-ctors.html)
什么导致Java和C++之间的这种差异?这是vtable初始化的时间吗?
编辑:我确实理解Java和C++机制.我想知道的是这个设计决定背后的见解.
请考虑以下示例代码:
class C
{
public:
int* x;
};
void f()
{
C* c = static_cast<C*>(malloc(sizeof(C)));
c->x = nullptr; // <-- here
}
Run Code Online (Sandbox Code Playgroud)
如果由于任何原因我不得不忍受未初始化的内存(当然,如果可能的话,我会打电话new C()),我仍然可以调用放置构造函数.但是,如果我省略这一点,如上所述,并手动初始化每个成员变量,是否会导致未定义的行为?即绕过构造函数本身未定义的行为,或者用类外的一些等效代码替换调用它是否合法?
(通过另一个完全不同的问题遇到这个问题;要求好奇......)
标准对程序退出期间的函数局部静态初始化有什么看法?
编辑:为了清楚起见,我的意思是代码示例中的情况 - 本地静态b是在构造另一个静态之后a构造的(因此应该b在之前销毁a),但b也在a的析构函数期间构造,所以它应该立即销毁吗?后?优?
我没有设法找到有关此事的任何参考资料。
我想知道这种情况是 UB,还是应该有一些定义的行为?
下面的代码就是一个例子:
struct B{};
void foo()
{
static B b;
}
struct A
{
~A() { foo(); }
};
int main()
{
static A a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,A 的析构函数会在程序退出时发生(因为它具有静态存储),并且它会尝试构造 B 静态实例。
我对 C++17 更感兴趣,如果它在这个主题上有什么不同的话。
object-lifetime ×10
c++ ×7
c# ×2
asp.net-core ×1
c ×1
c++17 ×1
coding-style ×1
function ×1
interface ×1
java ×1
malloc ×1
options ×1
parameters ×1
pointers ×1
raii ×1
scope ×1
shared-ptr ×1
static ×1
stylecop ×1
vptr ×1